Render your first PDF
Create, download, and preview a small invoice in a Nuxt application.
This tutorial starts after you install the module. It creates one invoice from typed data and returns it from a Nitro route.
Create the invoice template
Create pdfs/invoice.vue at the application root:
<script setup lang="ts">
type InvoiceProps = {
invoice: {
customer: string
number: string
total: string
}
}
const props = defineProps<InvoiceProps>()
definePdf<InvoiceProps>({
title: ({ invoice }) => `Invoice ${invoice.number}`,
filename: ({ invoice }) => `invoice-${invoice.number}.pdf`,
sampleData: {
invoice: {
customer: 'Ada Lovelace',
number: 'INV-001',
total: 'EUR 1,250.00',
},
},
})
</script>
<template>
<PdfDocument>
<PdfPage :style="{ fontSize: 11, padding: 48 }">
<PdfText :style="{ fontSize: 24, marginBottom: 24 }">
Invoice {{ props.invoice.number }}
</PdfText>
<PdfText>{{ props.invoice.customer }}</PdfText>
<PdfText :style="{ marginTop: 12 }">
Total: {{ props.invoice.total }}
</PdfText>
</PdfPage>
</PdfDocument>
</template>This is the minimum authoring contract:
- Templates live under
pdfs/. - The relative filename becomes the registry key.
pdfs/invoice.vuebecomespdf.invoice;pdfs/reports/monthly.vuebecomespdf['reports/monthly']. - Each template calls
definePdf()exactly once. - The template has one
PdfDocumentroot and at least onePdfPage. - Text belongs inside
PdfText. - Props are typed with
defineProps()and passed torender(). - Style keys use camelCase, such as
fontSizeandmarginBottom. sampleDataand preview scenarios exist only in development.
Add a Nitro route
Create server/api/invoice.get.ts:
import { pdf } from '#pdf'
export default defineEventHandler(async () => {
const result = await pdf.invoice.render({
invoice: {
customer: 'Ada Lovelace',
number: 'INV-001',
total: 'EUR 1,250.00',
},
})
return result.response()
})#pdf is generated from the files under pdfs/. Its render() method infers
the props from the matching Vue template. It is available to server code only.
Download the result
Keep the development server running. In another terminal, download the PDF:
curl -o invoice.pdf http://localhost:3000/api/invoiceOpen invoice.pdf in a PDF viewer. The route sends application/pdf with the
filename resolved by definePdf().
Open the development preview
Open http://localhost:3000/_pdf/invoice. The preview uses sampleData and
shows render diagnostics. The /_pdf routes and preview data do not exist in a
production build.
The next useful concepts are templates and the registry and the document tree.