@maistik/nuxt-pdf
v1.0.17
Published
A Nuxt 3 module for server-side PDF generation using Handlebars templates
Downloads
147
Maintainers
Readme
@maistik/nuxt-pdf
A powerful Nuxt 3/4 module for server-side PDF generation using Handlebars templates. Generate beautiful, data-driven PDFs with support for multiple providers (Gotenberg, Browserless, Puppeteer Core) and built-in internationalization.
Features
- 🎨 Handlebars Templates - Lightweight templating without Vue overhead
- 🌍 Internationalization - Built-in i18n support with
{{t}}helper - 🔄 Provider Agnostic - Support for Gotenberg, Browserless, and Puppeteer Core
- 🎯 SSR Safe - Everything runs server-side in Nitro/Node
- 🧩 Composable API - Easy-to-use
usePdf()composable - 📱 Responsive Design - CSS-based layouts with print media queries
- 🎪 Playground - Demo app with sample templates
Quick Start
Installation
npm install @maistik/nuxt-pdf handlebarsConfiguration
Add the module to your nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@maistik/nuxt-pdf'],
pdf: {
provider: 'puppeteer', // or 'gotenberg' or 'browserless'
components: ['pdf'],
sharedComponents: ['pdf/partials'],
enableI18n: true,
defaultLocale: 'en',
availableLocales: ['en', 'es', 'fr'],
i18nMessages: {
en: {
invoice: {
title: 'Invoice',
total: 'Total'
}
},
es: {
invoice: {
title: 'Factura',
total: 'Total'
}
}
},
providers: {
puppeteer: {
launchOptions: {
headless: true,
args: ['--no-sandbox']
}
}
}
}
})Create a Template
Create pdf/Invoice.hbs in your project:
<style>
@page { size: A4; margin: 20mm; }
body { font-family: Arial, sans-serif; }
.header { text-align: center; margin-bottom: 30px; }
.total { font-weight: bold; font-size: 18px; }
</style>
<div class="header">
<h1>{{t "invoice.title"}}</h1>
<p>Invoice #{{invoiceNumber}}</p>
</div>
<table>
{{#each items}}
<tr>
<td>{{this.description}}</td>
<td>{{formatCurrency this.price}}</td>
</tr>
{{/each}}
</table>
<div class="total">
{{t "invoice.total"}}: {{formatCurrency total}}
</div>Generate PDFs
Use the composable in your Vue components:
<script setup>
const { generate, download } = usePdf()
const generateInvoice = async () => {
const data = {
invoiceNumber: 'INV-001',
items: [
{ description: 'Service', price: 100 }
],
total: 100
}
// Generate and preview
const blob = await generate('Invoice', data, { format: 'A4' }, 'en')
// Or download directly
await download('Invoice', data, { format: 'A4' }, 'invoice.pdf', 'en')
}
</script>Providers
Puppeteer Core (Local)
Best for development and on-premise deployments:
pdf: {
provider: 'puppeteer',
providers: {
puppeteer: {
launchOptions: {
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
}
}
}
}Gotenberg (Docker)
Perfect for containerized environments:
pdf: {
provider: 'gotenberg',
providers: {
gotenberg: {
url: 'http://gotenberg:3000'
}
}
}Browserless (Cloud)
Great for serverless deployments:
pdf: {
provider: 'browserless',
providers: {
browserless: {
url: 'https://chrome.browserless.io',
apiKey: process.env.BROWSERLESS_API_KEY
}
}
}Built-in Helpers
Internationalization
{{t "invoice.title"}} <!-- Outputs localized text -->Currency Formatting
{{formatCurrency 1234.56}} <!-- $1,234.56 -->
{{formatCurrency 1234.56 "EUR"}} <!-- €1,234.56 -->Date Formatting
{{formatDate date}} <!-- 12/25/2024 -->
{{formatDate date "full"}} <!-- Wednesday, December 25, 2024 -->Number Formatting
{{formatNumber 1234.56}} <!-- 1,234.56 -->
{{formatNumber 0.15 style="percent"}} <!-- 15% -->Math Operations
{{add 10 5}} <!-- 15 -->
{{subtract 10 5}} <!-- 5 -->
{{multiply 10 5}} <!-- 50 -->
{{divide 10 5}} <!-- 2 -->
{{percentage 25 100}} <!-- 25% -->Custom Helpers
You can define your own custom helpers in the configuration:
pdf: {
customHelpers: {
// Simple value transformation
customFormat: (value: any) => `[${value}]`,
// String manipulation
repeat: (str: string, times: number) => str.repeat(times || 1),
// Block helper with conditional logic
ifEquals: function(this: any, arg1: any, arg2: any, options: any) {
return (arg1 === arg2) ? options.fn(this) : options.inverse(this)
}
}
}Use them in templates:
{{customFormat "hello"}} <!-- [hello] -->
{{repeat "★" 5}} <!-- ★★★★★ -->
{{#ifEquals status "active"}}Active User{{else}}Inactive User{{/ifEquals}}String Helpers
{{upper "hello world"}} <!-- HELLO WORLD -->
{{lower "HELLO WORLD"}} <!-- hello world -->
{{capitalize "hello world"}} <!-- Hello world -->
{{truncate "Long text here" 10}} <!-- Long text... -->Line Calculations
{{lineTotal quantity price}} <!-- quantity * price -->Template Features
Automatic Enrichment
The module automatically enriches your data based on template names:
Invoice Templates get:
subtotal- Sum of all line itemstax- Calculated tax amounttotal- Subtotal + taxdueDate- Calculated from issue date + payment terms
Sales Report Templates get:
quarters- Quarterly breakdown of sales datarating- Performance rating based on total sales
CSS Styling
Use standard CSS with print-specific rules:
@page {
size: A4;
margin: 20mm;
}
.page-break {
page-break-before: always;
}
@media print {
.no-break {
page-break-inside: avoid;
}
}Partials
Create reusable components in your sharedComponents directory:
<!-- pdf/partials/header.hbs -->
<div class="header">
<h1>{{title}}</h1>
<p>{{subtitle}}</p>
</div>Use in templates:
{{> header title="My Document" subtitle="Generated Report"}}API Reference
usePdf()
The main composable for PDF operations:
const {
generate, // (template, data, options?, locale?) => Promise<Blob>
download, // (template, data, options?, filename?, locale?) => Promise<void>
getAvailableLocales, // () => string[]
getDefaultLocale // () => string
} = usePdf()Options
interface PdfOptions {
format?: 'A4' | 'Letter' | 'Legal'
margin?: {
top?: number
bottom?: number
left?: number
right?: number
}
landscape?: boolean
printBackground?: boolean
pageBreak?: {
before?: string[]
after?: string[]
avoid?: string[]
}
}Development
Playground
The module includes a full playground application:
npm run devThis starts a demo app with sample Invoice and Sales Report templates in multiple languages.
Building
npm run buildTesting
npm run testExamples
Check out the playground/ directory for complete examples including:
- Invoice Template - Complete invoice with line items, taxes, and totals
- Sales Report Template - Comprehensive report with metrics and quarterly breakdown
- Multi-language Support - Templates in English, Spanish, and French
- Multiple Providers - Configuration examples for all supported providers
License
MIT
Contributing
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
