Skip to main content

Runtime and data loading

Where PDF templates execute and how data enters a render.

Each render creates a fresh Vue runtime-core application inside the Node process. Nuxt PDF mounts the document tree, lays it out, serializes the PDF, and then unmounts the Vue application.

Load data before rendering

Fetch and authorize data in normal server code. Pass the completed values through typed props:

ts
import { pdf } from '#pdf'

export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, 'id')
  const invoice = await loadAuthorizedInvoice(event, id)
  const result = await pdf.invoice.render({ invoice })

  return result.response()
})

This keeps request context, credentials, and database access in the Nuxt server where they belong. The template receives only the document data it needs.

Isolated Vue context

PDF templates can use local imports, Vue reactivity, lifecycle hooks, and provide/inject within the document tree. They do not inherit:

  • Nuxt app plugins or app-level provides;
  • global application components or directives;
  • browser globals such as window and document;
  • onServerPrefetch as a data-loading mechanism.

Async setup, top-level await, and defineAsyncComponent are rejected because layout cannot wait for document content to appear later.

Render stages and limits

One render covers metadata resolution, Vue mount, asset admission, layout, optional page-number passes, serialization, and output collection. The module applies one deadline and resource budget to that operation.

The deadline is checked between engine stages. It cannot interrupt a synchronous layout stage midway. Do not run untrusted template code in the process. Use the errors and limits reference to size admitted data, and the deployment guide to plan timeouts and queues.