Skip to main content

PDFs authored as Vue components.

Nuxt PDF renders documents on the server from ordinary Vue SFCs. It uses Vue for authoring. React PDF's framework-neutral engine provides layout and serialization. React is not a production dependency.

pnpm add @lupinum/nuxt-pdf
<script setup lang="ts">
const props = defineProps<{ invoice: { number: string; total: string } }>()

definePdf({
  title: ({ invoice }) => `Invoice ${invoice.number}`,
  filename: ({ invoice }) => `invoice-${invoice.number}.pdf`,
})
</script>

<template>
  <PdfDocument>
    <PdfPage size="A4" :style="{ padding: 48 }">
      <PdfText :style="{ fontSize: 24 }">Invoice {{ props.invoice.number }}</PdfText>
      <PdfText>Total: {{ props.invoice.total }}</PdfText>
    </PdfPage>
  </PdfDocument>
</template>

Vue authoring, PDF output

Compose documents with typed props, v-if, keyed v-for, slots, and local components. A small set of thin primitives maps to the layout engine.

Server-only rendering

The engine is Node server-only, with no client build step. React PDF runtimes are absent from the client bundle and from production dependencies.

Typed #pdf registry

Discovered templates generate an inspectable #pdf module. Property access and literal names infer each SFC's props; a marked escape hatch covers runtime strings.

Contents, links, bookmarks

A multi-pass layout loop resolves table-of-contents page numbers; #id links and a bookmark outline follow the component tree. Non-convergence fails closed.

Fail-closed resources

Local images and fonts are signature-checked and embedded at build. Remote fetching is off until an operator sets an explicit allowlist.

Test with a real render

@lupinum/nuxt-pdf/test renders a template through the real pipeline and asserts on extracted text, links, outline, page count, and raster baselines.

Render your first document.