Node API
renderToStream
Renders a PDF document and returns a readable stream, ideal for piping directly to HTTP responses.
Signature
ts
function renderToStream(
element: Component,
props?: Record<string, unknown>
): Promise<ReadableStream>Usage
ts
import { renderToStream } from '@vuepdf/renderer'
import MyDocument from './MyDocument.vue'
app.get('/pdf', async (req, res) => {
const stream = await renderToStream(MyDocument)
res.setHeader('Content-Type', 'application/pdf')
stream.pipe(res)
})Nuxt Server Route
In a Nuxt app, a route under server/api/ can stream the PDF straight to the client with h3's sendStream:
server/api/report.get.ts
// server/api/report.get.ts
import { renderToStream } from '@vuepdf/renderer'
import ReportDocument from '../../components/pdf/ReportDocument.vue'
export default defineEventHandler(async (event) => {
const { title = 'Report' } = getQuery(event) as { title?: string }
setHeader(event, 'content-type', 'application/pdf')
setHeader(event, 'content-disposition', 'inline; filename="report.pdf"')
return sendStream(event, await renderToStream(ReportDocument, { title }))
})components/pdf/ReportDocument.vue
<!-- components/pdf/ReportDocument.vue -->
<script setup lang="ts">
import { Document, Page, Text } from '@vuepdf/renderer/components'
defineProps<{ title: string }>()
</script>
<template>
<Document :title="title">
<Page size="A4" :style="{ padding: 48, fontSize: 12 }">
<Text :style="{ fontSize: 24, marginBottom: 12 }">
{{ title }}
</Text>
<Text>
Generated on the server with renderToStream.
</Text>
</Page>
</Document>
</template>vue
<template>
<a href="/api/report?title=Quarterly%20Report" target="_blank">
Open the PDF
</a>
</template> Keep PDF component imports inside the document component. Nitro can import the document SFC from the server route, and the document can import primitives from @vuepdf/renderer/components.
For generated trees without Vue templates, @vuepdf/renderer/primitives remains available.
Importing a
.vue document from a server route requires the @vuepdf/nuxt module. Nitro bundles server/ without Vue support, so the module registers a Vue SFC plugin for it; without that the build fails with rollup-plugin-inject: failed to parse YourDocument.vue. Outside Nuxt — plain Node or Express — either precompile the SFC in your own build, or build the document from @vuepdf/renderer/primitives instead. Need the same document in the browser? Render it client-side with usePDF or PDFDownloadLink.
Related
Use renderToBuffer when you need the bytes in memory rather than a stream — for caching, uploading, or setting an explicit content-length.