Module options
The pdf.* configuration for font declarations, the remote allowlist, and render limits.
Module options live under the pdf key in nuxt.config.ts:
export default defineNuxtConfig({
modules: ["@lupinum/nuxt-pdf"],
pdf: {
fonts: [/* entries */],
remote: {/* options */},
limits: {/* options */},
},
});Every key is optional. With none set, the module renders with built-in fonts, uses only local assets, performs zero network I/O, and bounds every render with the default render limits below.
pdf.fonts
An array of font-face declarations. Each face registers one weight/style of a
font found in pdfs/fonts:
export default defineNuxtConfig({
pdf: {
fonts: [
{ family: "Invoice Sans", src: "Regular.ttf", fontWeight: 400, fontStyle: "normal" },
{ family: "Invoice Sans", src: "Bold.ttf", fontWeight: 700, fontStyle: "normal" },
],
},
})| Field | Type | Required | Description |
|---|---|---|---|
family | string | yes | The family name referenced in fontFamily style values |
src | string | yes | TTF/OTF filename relative to pdfs/fonts |
fontWeight | number | PdfFontWeightName | no | Numeric weight or a name such as "bold", "medium", or "light" |
fontStyle | 'normal' | 'italic' | 'oblique' | no | The face style |
Register one entry per weight/style you use. Sources are signature- and size-checked (5 MB cap) and embedded into the build. See Images & fonts for the validation boundary.
pdf.remote
Opt-in remote fetching for images only. Absent by default, which keeps
the module fully offline; when present, allow must list at least one
https:// prefix.
export default defineNuxtConfig({
pdf: {
remote: {
allow: [
"https://cdn.example.com/brand/",
"https://images.example.com/logos/",
],
timeoutMs: 10_000,
},
},
})| Field | Type | Default | Description |
|---|---|---|---|
allow | string[] | Required | Exact allowlisted https://host/path/ prefixes with a trailing slash |
timeoutMs | number | 10_000 | Per-hop fetch timeout |
Invalid entries fail fast at module setup: non-https, credentialed, or
query/fragment-bearing entries, wildcard hosts, and prefixes without a trailing
slash are all rejected. The module checks each redirect, limits streamed bytes,
validates signatures, and does not forward credentials. See
Images & fonts.
pdf.limits
The one canonical resource budget for every render. Defaults apply even when
pdf.limits is absent.
export default defineNuxtConfig({
pdf: {
limits: {
timeoutMs: 30_000,
maxPages: 2_000,
maxNodes: 50_000,
maxOutputBytes: 67_108_864,
},
},
})| Field | Type | Default | Description |
|---|---|---|---|
timeoutMs | number | 30_000 | Time budget for the whole public render (metadata evaluation, mount, layout, all passes, serialization) |
maxPages | number | 2_000 | Maximum laid-out page count |
maxNodes | number | 50_000 | Maximum mounted tree nodes |
maxTreeDepth | number | 128 | Maximum mounted tree depth |
maxTextCharacters | number | 2_000_000 | Maximum Unicode code points in text nodes |
maxImages | number | 256 | Maximum image nodes |
maxImageBytes | number | 10_485_760 | Maximum source bytes per unique image |
maxTotalImageBytes | number | 33_554_432 | Maximum source bytes across unique images |
maxImagePixels | number | 25_000_000 | Maximum decoded pixels per unique image |
maxTotalImagePixels | number | 100_000_000 | Maximum decoded pixels across unique images |
maxRemoteRequests | number | 32 | Maximum remote HTTP requests, including redirect hops |
maxRemoteConcurrency | number | 4 | Maximum simultaneous remote HTTP requests |
maxOutputBytes | number | 67_108_864 | Maximum completed PDF bytes |
Every field is an optional positive safe integer; a non-positive, non-integer, or non-numeric value fails fast at module setup. Omitting one field keeps its default.
When a limit is exceeded the render fails with a PDF_LIMIT_EXCEEDED
NuxtPdfError:
maxPagesis checked right after layout (before serialization) on both the single-pass and multi-pass paths; the error names the page count, the cap, and the config key.timeoutMsbounds the entire public render with a single deadline that starts before metadata evaluation. Upstream layout is not abortable mid-step, so the budget is checked between engine stages and passes. It is a deadline, not hard cancellation, and a single engine stage can overshoot it by its own duration. The error names the elapsed budget. The reporteddiagnostics.durationMscovers the same operation.- Tree, text, and image-count limits are checked on the mounted tree after Vue mount (and again after every multi-pass page-number feed). They reject excess content; they do not isolate allocation during mount. Image byte and decoded-pixel limits are checked before engine admission with one render-wide budget. Output is collected into one completed buffer and discarded atomically when its cap is exceeded.
Hard cancellation is not claimed. Vue component/setup closures are the canonical document source and are not transferable to a portable Nitro worker; introducing a worker-only bundle or second serialized schema would violate the one-tree architecture. Keep untrusted template code out of the process and use the admission limits to bound document data.