Skip to main content

The document tree

PDF primitives, valid nesting, Vue composition, and dynamic text.

Nuxt PDF renders a closed tree of PDF primitives. It does not render HTML or DOM components.

Root and page structure

Each template has one PdfDocument root and at least one PdfPage:

vue
<PdfDocument>
  <PdfPage>
    <PdfView>
      <PdfText>Quarterly report</PdfText>
    </PdfView>
  </PdfPage>
</PdfDocument>

The main primitives are:

PrimitiveRole
PdfDocumentDocument root and metadata
PdfPageOne fixed or wrapping page
PdfViewFlex layout container
PdfTextText content and inline text runs
PdfImagePNG or JPEG image
PdfLinkExternal or internal link
PdfNotePDF note annotation

The primitive reference lists the closed prop and nesting surface. The SVG guide covers vector graphics.

Put all visible text inside PdfText. Text placed directly under PdfPage or PdfView fails with PDF_TREE_INVALID; it is not discarded.

Vue composition

Use local Vue components, typed props, slots, v-if, and keyed v-for. Keep components owned by one document under a document-specific directory:

pdfs/components/invoice/InvoiceLine.vue
<script setup lang="ts">
defineProps<{ label: string; amount: string }>()
</script>

<template>
  <PdfView :style="{ flexDirection: 'row', justifyContent: 'space-between' }">
    <PdfText>{{ label }}</PdfText>
    <PdfText>{{ amount }}</PdfText>
  </PdfView>
</template>

Import the component from the template. Nuxt app plugins, global components, directives, and app-level provides do not enter the PDF tree.

Dynamic page text

Use a synchronous render callback for values known during pagination:

vue
<PdfText
  fixed
  :render="({ pageNumber, totalPages }) => `Page ${pageNumber} of ${totalPages}`"
/>

fixed repeats the node on each page. The callback returns a string or number. For a table of contents that reads destination page numbers, use usePdfPageNumbers().

Invalid nesting, unknown primitive props, DOM attributes, Teleport, and v-show fail instead of producing incomplete PDF content.