Skip to main content

definePdf

The compile-time definition for render metadata, development preview data, and the multi-pass limit.

Each pdfs/*.vue template calls definePdf exactly once. It is a compile-time macro (like defineProps); it declares render metadata and development-only preview data and returns nothing.

ts
definePdf<Props>({
  title: props => `Report ${props.id}`,
  filename: props => `report-${props.id}.pdf`,
  language: 'en-GB',
  maxPasses: 5,
  sampleData: { id: 'sample' },
  scenarios: {
    long: { id: 'long-report' },
  },
})

Options

OptionTypeDefaultDescription
titlestring | (props) => stringNoneDocument title. A static string or a function of props.
filenamestring | (props) => stringNoneDownload filename, sanitized before use in content-disposition.
languagestringNoneDocument language tag written to the info dictionary (for example "en-US").
maxPassesnumber5Maximum layout passes before the multi-pass loop declares non-convergence and throws PDF_LIMIT_EXCEEDED. A positive integer.
sampleDataPropsNoneProps used for the default development preview.
scenariosRecord<string, Props>NoneNamed prop sets. Each set becomes a preview tab and a ?scenario= query.

The Props type parameter ties title, filename, sampleData, and each scenario to the SFC's own props, so a mismatch is a type error.

maxPasses is only relevant to documents that read usePdfPageNumbers(). Every other document renders in a single pass regardless of the value.

Metadata resolution

title and filename functions receive the render props and must return a string synchronously. They are resolved at render time. When title or language is present, it is authoritative and overrides the corresponding prop authored on PdfDocument. When it is absent, the PdfDocument value remains the rendered fallback. The authoritative values are reapplied after every page-number update, so a multi-pass document cannot restore stale root metadata between layout passes.

resolveMetadata(props) on the generated template handle resolves only the definePdf values without mounting the component. filename controls the default response filename; it is not a PdfDocument prop.

Preview data is development-only

sampleData and scenarios are used only by the development preview. They are kept in an internal preview sidecar and are never exposed by the public PdfTemplate handle.

Production compilation goes further than ignoring these fields: it structurally reconstructs the definition from title, filename, language, and maxPasses, omitting the preview expressions before the Nitro server bundle is emitted. Do not put production runtime state or secrets in preview fixtures; keep them representative, disposable development data.

definePdf() is module-scoped, like Vue's other hoisted compiler macros. Its values may be inline or imported from another module, but they cannot reference a variable declared locally in <script setup>; that fails compilation instead of producing a development-only ReferenceError. Keep imported preview-data modules side-effect-free so the production bundler can remove the now-unused import together with the omitted fixture fields.

Scenarios in the preview

ts
definePdf<Props>({
  sampleData: { id: 'sample' },
  scenarios: {
    long: { id: 'long-report' },
    empty: { id: 'no-sections' },
  },
})

The long scenario is available at /_pdf/report?scenario=long. An unknown scenario name returns a 404 listing the available names.