@lupinum/nuxt-pdf 0.4.0-beta.4 → 0.4.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/CONFORMANCE.md +4 -4
  3. package/README.md +54 -12
  4. package/dist/agent/AGENTS.md +44 -0
  5. package/dist/agent/pages/docs/examples/supported-behavior.md +75 -0
  6. package/dist/agent/pages/docs/examples.md +163 -0
  7. package/dist/agent/pages/docs/getting-started/installation.md +75 -0
  8. package/dist/agent/pages/docs/getting-started/quickstart.md +126 -0
  9. package/dist/agent/pages/docs/getting-started.md +63 -0
  10. package/dist/agent/pages/docs/guides/contents-links-bookmarks.md +123 -0
  11. package/dist/agent/pages/docs/guides/deployment.md +118 -0
  12. package/dist/agent/pages/docs/guides/errors-and-debugging.md +90 -0
  13. package/dist/agent/pages/docs/guides/images-and-fonts.md +102 -0
  14. package/dist/agent/pages/docs/guides/recipes.md +258 -0
  15. package/dist/agent/pages/docs/guides/remote-images.md +72 -0
  16. package/dist/agent/pages/docs/guides/reusable-components.md +81 -0
  17. package/dist/agent/pages/docs/guides/standalone-node.md +107 -0
  18. package/dist/agent/pages/docs/guides/svg-graphics.md +165 -0
  19. package/dist/agent/pages/docs/guides/testing.md +119 -0
  20. package/dist/agent/pages/docs/learn/document-tree.md +91 -0
  21. package/dist/agent/pages/docs/learn/runtime-and-data.md +63 -0
  22. package/dist/agent/pages/docs/learn/styling-and-layout.md +79 -0
  23. package/dist/agent/pages/docs/learn/templates-and-registry.md +96 -0
  24. package/dist/agent/pages/docs/reference/composables.md +55 -0
  25. package/dist/agent/pages/docs/reference/define-pdf.md +96 -0
  26. package/dist/agent/pages/docs/reference/errors-and-limits.md +89 -0
  27. package/dist/agent/pages/docs/reference/module-options.md +104 -0
  28. package/dist/agent/pages/docs/reference/page-sizes.md +54 -0
  29. package/dist/agent/pages/docs/reference/primitives.md +216 -0
  30. package/dist/agent/pages/docs/reference/registry.md +185 -0
  31. package/dist/agent/pages/docs/reference/standalone.md +53 -0
  32. package/dist/agent/pages/docs/reference/styles.md +176 -0
  33. package/dist/agent/pages/docs/reference/test-utilities.md +128 -0
  34. package/dist/module.json +1 -1
  35. package/dist/module.mjs +1 -1
  36. package/dist/test.mjs +13 -1
  37. package/package.json +27 -48
@@ -0,0 +1,104 @@
1
+ ---
2
+ title: "Module options"
3
+ description: "Build-time configuration for registered fonts, remote images, and render budgets."
4
+ url: "https://nuxt-pdf.lupinum.com/docs/reference/module-options"
5
+ route: "/docs/reference/module-options"
6
+ locale: "en"
7
+ section: "Documentation"
8
+ collection: "docs"
9
+ source: "ginko-content"
10
+ ---
11
+
12
+ # Module options
13
+
14
+ > Build-time configuration for registered fonts, remote images, and render budgets.
15
+
16
+ Set module options under `pdf` in `nuxt.config.ts`:
17
+
18
+ ```ts [nuxt.config.ts]
19
+ export default defineNuxtConfig({
20
+ modules: ['@lupinum/nuxt-pdf'],
21
+ pdf: {
22
+ fonts: [],
23
+ limits: {},
24
+ remote: undefined,
25
+ },
26
+ })
27
+ ```
28
+
29
+ | Option | Type | Default | Behavior |
30
+ | --- | --- | --- | --- |
31
+ | `fonts` | `PdfFontDeclaration[]` | `[]` | Registers local TTF, OTF, or WOFF2 faces from `pdfs/fonts`. |
32
+ | `remote` | `RemoteAssetOptions` | `undefined` | Enables allowlisted HTTPS image requests. No remote request is admitted when absent. |
33
+ | `limits` | `PdfLimitsOptions` | All documented defaults | Overrides individual fields in the shared render budget. See [Errors and limits](/raw/docs/reference/errors-and-limits.md). |
34
+
35
+ Unknown `pdf` keys fail during module setup.
36
+
37
+ ## pdf.fonts
38
+
39
+ Each entry registers one font face:
40
+
41
+ ```ts [nuxt.config.ts]
42
+ export default defineNuxtConfig({
43
+ pdf: {
44
+ fonts: [
45
+ {
46
+ family: 'Invoice Sans',
47
+ src: 'InvoiceSans-Regular.ttf',
48
+ fontStyle: 'normal',
49
+ fontWeight: 400,
50
+ },
51
+ ],
52
+ },
53
+ })
54
+ ```
55
+
56
+ | Field | Type | Required | Default | Behavior |
57
+ | --- | --- | --- | --- | --- |
58
+ | `family` | `string` | Yes | Required | Family used by the `fontFamily` style property. |
59
+ | `src` | `string` | Yes | Required | TTF, OTF, or WOFF2 path relative to `pdfs/fonts`. |
60
+ | `fontWeight` | `number \| PdfFontWeightName` | No | `400` | Numeric or named weight. |
61
+ | `fontStyle` | `'normal' \| 'italic' \| 'oblique'` | No | `'normal'` | Face style. |
62
+
63
+ Register each weight and style used by a document. Invalid declarations and
64
+ font files throw `TypeError` during module setup. See
65
+ [Add images and fonts](/raw/docs/guides/images-and-fonts.md).
66
+
67
+ ## pdf.remote
68
+
69
+ `remote` admits HTTPS images whose URL starts with an allowed prefix:
70
+
71
+ ```ts [nuxt.config.ts]
72
+ export default defineNuxtConfig({
73
+ pdf: {
74
+ remote: {
75
+ allow: ['https://cdn.example.com/brand/'],
76
+ timeoutMs: 10_000,
77
+ },
78
+ },
79
+ })
80
+ ```
81
+
82
+ | Field | Type | Required | Default | Behavior |
83
+ | --- | --- | --- | --- | --- |
84
+ | `allow` | `string[]` | Yes | Required | Non-empty list of exact `https://host/path/` prefixes. |
85
+ | `timeoutMs` | `number` | No | `10_000` | Timeout for each request or redirect hop. |
86
+
87
+ Allowlist prefixes require a trailing slash. They cannot contain credentials,
88
+ queries, fragments, wildcards, or a non-HTTPS scheme. The
89
+ [remote-image guide](/raw/docs/guides/remote-images.md) defines request and redirect
90
+ behavior.
91
+
92
+ ## Exported types
93
+
94
+ Import these types from `@lupinum/nuxt-pdf`:
95
+
96
+ | Export | Describes |
97
+ | --- | --- |
98
+ | `ModuleOptions` | Complete `pdf` module options. |
99
+ | `PdfFontDeclaration` | One registered font face. |
100
+ | `PdfFontStyle` | Accepted font styles. |
101
+ | `PdfFontWeight` | Numeric or named font weight. |
102
+ | `PdfFontWeightName` | Accepted named font weights. |
103
+ | `RemoteAssetOptions` | Remote image allowlist and timeout. |
104
+ | `PdfLimitsOptions` | Optional render-limit overrides. |
@@ -0,0 +1,54 @@
1
+ ---
2
+ title: "Page sizes"
3
+ description: "Named and custom page dimensions accepted by PdfPage."
4
+ url: "https://nuxt-pdf.lupinum.com/docs/reference/page-sizes"
5
+ route: "/docs/reference/page-sizes"
6
+ locale: "en"
7
+ section: "Documentation"
8
+ collection: "docs"
9
+ source: "ginko-content"
10
+ ---
11
+
12
+ # Page sizes
13
+
14
+ > Named and custom page dimensions accepted by PdfPage.
15
+
16
+ Set `PdfPage.size` to an uppercase named size or to explicit dimensions. The
17
+ default is `A4`.
18
+
19
+ ```vue
20
+ <PdfPage size="LETTER">
21
+ <PdfText>Letter page</PdfText>
22
+ </PdfPage>
23
+ ```
24
+
25
+ Page-size names are case-sensitive:
26
+
27
+ | Family | Accepted names |
28
+ | --- | --- |
29
+ | ISO A | `4A0`, `2A0`, `A0`, `A1`, `A2`, `A3`, `A4`, `A5`, `A6`, `A7`, `A8`, `A9`, `A10` |
30
+ | ISO B | `B0`, `B1`, `B2`, `B3`, `B4`, `B5`, `B6`, `B7`, `B8`, `B9`, `B10` |
31
+ | ISO C | `C0`, `C1`, `C2`, `C3`, `C4`, `C5`, `C6`, `C7`, `C8`, `C9`, `C10` |
32
+ | Raw format | `RA0`, `RA1`, `RA2`, `RA3`, `RA4` |
33
+ | Supplementary raw format | `SRA0`, `SRA1`, `SRA2`, `SRA3`, `SRA4` |
34
+ | North American and other | `EXECUTIVE`, `FOLIO`, `LEGAL`, `LETTER`, `TABLOID`, `ID1` |
35
+
36
+ ## Custom dimensions
37
+
38
+ Use a two-value tuple or a width/height object. A unitless number is a PDF
39
+ point. String dimensions accept `pt`, `in`, `mm`, `cm`, or `px`:
40
+
41
+ ```vue
42
+ <PdfPage :size="['210mm', '297mm']">
43
+ <PdfText>Custom A4 dimensions</PdfText>
44
+ </PdfPage>
45
+ ```
46
+
47
+ ```vue
48
+ <PdfPage :size="{ width: '4in', height: '6in' }">
49
+ <PdfText>Shipping label</PdfText>
50
+ </PdfPage>
51
+ ```
52
+
53
+ `px` uses the page's `dpi` prop. The default DPI is `72`. Use `orientation` to
54
+ swap portrait and landscape dimensions without reversing the size tuple.
@@ -0,0 +1,216 @@
1
+ ---
2
+ title: "Primitives"
3
+ description: "Prop tables for every document and SVG primitive, drawn from the shipped type definitions."
4
+ url: "https://nuxt-pdf.lupinum.com/docs/reference/primitives"
5
+ route: "/docs/reference/primitives"
6
+ locale: "en"
7
+ section: "Documentation"
8
+ collection: "docs"
9
+ source: "ginko-content"
10
+ ---
11
+
12
+ # Primitives
13
+
14
+ > Prop tables for every document and SVG primitive, drawn from the shipped type definitions.
15
+
16
+ Every primitive is an auto-registered global component. The tables below are
17
+ drawn from the shipped prop types. `style` values use Nuxt PDF's framework-owned
18
+ `PdfStyle` contract, not CSS or the wider upstream stylesheet types (see
19
+ [Styling and layout](/raw/docs/learn/styling-and-layout.md).
20
+
21
+ The same surface is enforced after Vue mounts the tree. Each primitive has a
22
+ closed runtime prop allowlist; unknown props, DOM/event attributes, and props
23
+ used on the wrong primitive fail with `PDF_TREE_INVALID` rather than passing
24
+ through or silently doing nothing.
25
+
26
+ ## Shared base props
27
+
28
+ `PdfPage`, `PdfView`, page-flow `PdfText`, `PdfImage`, `PdfLink`, and `PdfNote`
29
+ share these:
30
+
31
+ | Prop | Type | Default | Description |
32
+ | --- | --- | --- | --- |
33
+ | `id` | `string` | None | Makes the node a named destination for `#id` links and page-number resolution. |
34
+ | `fixed` | `boolean` | `false` | Repeats the node on every page of its flow. |
35
+ | `break` | `boolean` | `false` | Forces a page break before the node. |
36
+ | `minPresenceAhead` | `number` | `0` | Minimum space in points that must follow, or the node moves to the next page. |
37
+ | `debug` | `boolean` | `false` | Draws the node's layout box for debugging. |
38
+ | `style` | `PdfStyleValue` | None | A style object or nested array. `false`, `null`, and `undefined` entries are ignored. |
39
+
40
+ `PdfPage`, `PdfView`, `PdfText`, and `PdfImage` additionally accept `bookmark`
41
+ (`string`, or `{ title, expanded? }`) to build the outline.
42
+
43
+ ## PdfDocument
44
+
45
+ The root. Carries document metadata; takes no base props.
46
+
47
+ | Prop | Type | Default | Description |
48
+ | --- | --- | --- | --- |
49
+ | `title`, `author`, `subject`, `keywords` | `string` | None | Info-dictionary metadata. |
50
+ | `creator`, `producer` | `string` | `'nuxt-pdf'` | Info-dictionary producer metadata. |
51
+ | `language` | `string` | None | Document language tag. |
52
+ | `creationDate` | `Date` | Current render date | Info-dictionary creation date. |
53
+ | `pdfVersion` | `'1.3'` through `'1.7'` or `'1.7ext3'` | `'1.3'` | PDF version written to the catalog. |
54
+ | `pageLayout` | `'singlePage' \| 'oneColumn' \| 'twoColumnLeft' \| 'twoColumnRight' \| 'twoPageLeft' \| 'twoPageRight'` | None | Reader page layout. |
55
+
56
+ Reader page mode, encryption passwords, and PDF permission flags are not public
57
+ props. Their serialized behavior is not part of the current public contract.
58
+
59
+ `modificationDate` is also absent. The pinned engine writes its
60
+ upstream prop under a non-standard custom key rather than the PDF `ModDate`
61
+ entry, so exposing it would promise metadata that common readers do not see.
62
+
63
+ When `definePdf` supplies `title` or `language`, that value is authoritative and
64
+ overrides the corresponding `PdfDocument` prop. Without a definition value, the
65
+ root prop is preserved as the rendered fallback. Nuxt PDF reapplies the
66
+ authoritative values after each page-number update in a multi-pass render.
67
+
68
+ ## PdfPage
69
+
70
+ | Prop | Type | Default | Description |
71
+ | --- | --- | --- | --- |
72
+ | `size` | `PdfPageSizeName \| [w, h] \| { width, height }` | `'A4'` | Uppercase named size or explicit dimensions. See [Page sizes](/raw/docs/reference/page-sizes.md). |
73
+ | `orientation` | `'portrait' \| 'landscape'` | `'portrait'` | Page orientation. |
74
+ | `dpi` | `number` | `72` | DPI used for `px` dimensions. |
75
+ | `wrap` | `boolean` | `true` | Paginates content. `false` grows the page to fit. |
76
+
77
+ Plus the base and bookmark props.
78
+
79
+ ## PdfView
80
+
81
+ The flexbox container. Base and bookmark props, plus:
82
+
83
+ | Prop | Type | Default | Description |
84
+ | --- | --- | --- | --- |
85
+ | `wrap` | `boolean` | `true` | Allows the view to split across a page boundary. |
86
+
87
+ ## PdfText
88
+
89
+ The only container for text has two context-specific prop branches.
90
+
91
+ In normal page flow it accepts the base and bookmark props, plus:
92
+
93
+ | Prop | Type | Default | Description |
94
+ | --- | --- | --- | --- |
95
+ | `wrap` | `boolean` | `true` | Allows text to split across pages. |
96
+ | `widows` | `number` | `2` | Minimum lines kept together at a page top. |
97
+ | `orphans` | `number` | `2` | Minimum lines kept together at a page bottom. |
98
+ | `render` | `({ pageNumber, totalPages, subPageNumber, subPageTotalPages }) => string \| number \| null \| undefined` | None | Synchronous dynamic text. |
99
+ | `hyphenationCallback` | `(word: string) => string[]` | Engine default | Returns custom hyphenation break points. |
100
+
101
+ Inside `PdfSvg`, it instead accepts:
102
+
103
+ | Prop | Type | Default | Description |
104
+ | --- | --- | --- | --- |
105
+ | `x`, `y` | `PdfSvgLength` | Required | SVG text coordinates. |
106
+ | `fill` | `string` | None | Direct SVG text paint color. |
107
+ | `style` | `PdfStyleValue` | None | Text metrics such as font family and size. `color` is not SVG paint. |
108
+ | `hyphenationCallback` | `(word: string) => string[]` | Engine default | Returns custom hyphenation break points. |
109
+
110
+ SVG text rejects page-flow-only props such as `id`, `bookmark`, `fixed`,
111
+ `break`, `wrap`, `widows`, `orphans`, and `render`.
112
+
113
+ ## PdfImage
114
+
115
+ Base and bookmark props, plus:
116
+
117
+ | Prop | Type | Default | Description |
118
+ | --- | --- | --- | --- |
119
+ | `src` | `PdfImageSource` | Required | Image source. |
120
+
121
+ `PdfImageSource` is a `pdfs/assets`-relative path, a `Uint8Array`/`ArrayBuffer`,
122
+ `{ data, format: 'png' \| 'jpg' }`, or `{ uri, format? }`.
123
+
124
+ ## PdfLink
125
+
126
+ Base props (no bookmark), plus:
127
+
128
+ | Prop | Type | Default | Description |
129
+ | --- | --- | --- | --- |
130
+ | `href` | `string` | Required | External `https:` or `mailto:` URL, or a `#id` internal destination. |
131
+ | `wrap` | `boolean` | `true` | Allows the link to split across pages. |
132
+ | `hitSlop` | `{ top?, right?, bottom?, left? }` | None | Expands the clickable area. |
133
+
134
+ ## PdfNote
135
+
136
+ A sticky-note annotation. Base props only; its text comes from its content.
137
+
138
+ ---
139
+
140
+ ## SVG primitives
141
+
142
+ SVG primitives render inside a `PdfSvg`. Paint, geometry, clipping, and
143
+ transforms are direct props. `PdfG` and the shape primitives have no generic
144
+ `style` prop, so there is no style-precedence path; kebab-case Vue attributes
145
+ are normalized to the equivalent camelCase key. See
146
+ [SVG graphics](/raw/docs/guides/svg-graphics.md).
147
+
148
+ `PdfSvgNumber` is a finite number or numeric string. `PdfSvgLength` additionally
149
+ accepts a numeric percentage string where the individual prop permits it.
150
+ `strokeWidth` is never a percentage. Non-negative geometry and unit-interval
151
+ opacity/stop ranges are checked at runtime.
152
+
153
+ ### Shared SVG presentation props
154
+
155
+ Available on `PdfG`, `PdfPath`, `PdfRect`, `PdfCircle`, `PdfEllipse`, `PdfLine`,
156
+ `PdfPolyline`, and `PdfPolygon`:
157
+
158
+ | Prop | Type |
159
+ | --- | --- |
160
+ | `fill`, `stroke` | `string` |
161
+ | `fillOpacity`, `strokeOpacity` | `PdfSvgLength` (0 to 1 or 0% to 100%) |
162
+ | `strokeWidth` | `PdfSvgNumber` (non-negative) |
163
+ | `strokeLinecap` | `'butt' \| 'round' \| 'square'` |
164
+ | `strokeLinejoin` | `'miter' \| 'round' \| 'bevel'` |
165
+ | `transform` | `PdfSvgTransform`. One to three unitless `translate(...)` or `rotate(...)` operations. |
166
+ | `clipPath` | `string` with the value `url(#id)` |
167
+
168
+ ### Geometry props
169
+
170
+ | Component | Own props |
171
+ | --- | --- |
172
+ | `PdfSvg` | `viewBox`, `width`, `height`, plus page-flow `style` (not SVG presentation) |
173
+ | `PdfG` | _(presentation props only)_ |
174
+ | `PdfPath` | `d` **(required)** |
175
+ | `PdfRect` | `x`, `y`, `width` **(required)**, `height` **(required)**, `rx`, `ry` |
176
+ | `PdfCircle` | `cx`, `cy`, `r` **(required)** |
177
+ | `PdfEllipse` | `cx`, `cy`, `rx` **(required)**, `ry` **(required)** |
178
+ | `PdfLine` | `x1`, `y1`, `x2`, `y2` **(all required)** |
179
+ | `PdfPolyline` / `PdfPolygon` | `points` **(required)** |
180
+ | `PdfDefs` | None. It holds definitions that other elements can reference. |
181
+ | `PdfClipPath` | `id` **(required)** |
182
+ | `PdfLinearGradient` | `id` **(required)**, `x1`, `y1`, `x2`, `y2` |
183
+ | `PdfRadialGradient` | `id` **(required)**, `cx`, `cy`, `r`, `fx`, `fy` |
184
+ | `PdfStop` | `offset` **(required)**, `stopColor` **(required)**, `stopOpacity` |
185
+ | `PdfTspan` | `x`, `y`, `fill` only |
186
+
187
+ Alternate gradient coordinate systems, transforms, inheritance, and SVG
188
+ `preserveAspectRatio` modes are not public props. See
189
+ [Supported behavior and limitations](/raw/docs/examples/supported-behavior.md).
190
+
191
+ Each `PdfSvg` accepts at most one direct `PdfDefs` child. Definition ids are
192
+ safe, unique, and scoped to that one SVG. `fill="url(#id)"` must resolve to a
193
+ linear or radial gradient; `clipPath="url(#id)"` must resolve to a
194
+ `PdfClipPath`. Missing, malformed, or incompatible references fail with
195
+ `PDF_TREE_INVALID`.
196
+
197
+ Explicit zero has SVG semantics: zero fill opacity is transparent, zero stroke
198
+ width removes the stroke instead of requesting a PDF hairline, and supported
199
+ gradient coordinates remain zero. The engine repairs upstream truthiness
200
+ fallbacks after layout and before serialization.
201
+
202
+ ## Exported primitive types
203
+
204
+ Import prop and value types from `@lupinum/nuxt-pdf` when you type reusable
205
+ document components:
206
+
207
+ | Area | Exports |
208
+ | --- | --- |
209
+ | Shared | `PdfBaseProps`, `PdfBookmark` |
210
+ | Document flow | `PdfDocumentProps`, `PdfPageProps`, `PdfViewProps`, `PdfTextProps`, `PdfImageProps`, `PdfLinkProps`, `PdfNoteProps` |
211
+ | Images | `PdfImageSource` |
212
+ | Page dimensions | `PdfPageDimension`, `PdfPageSize`, `PdfPageSizeName`, `PdfPageUnit` |
213
+ | SVG containers | `PdfSvgProps`, `PdfGProps`, `PdfDefsProps`, `PdfClipPathProps` |
214
+ | SVG shapes | `PdfPathProps`, `PdfRectProps`, `PdfCircleProps`, `PdfEllipseProps`, `PdfLineProps`, `PdfPolylineProps`, `PdfPolygonProps` |
215
+ | SVG gradients and text | `PdfLinearGradientProps`, `PdfRadialGradientProps`, `PdfStopProps`, `PdfTspanProps` |
216
+ | SVG values | `PdfSvgNumber`, `PdfSvgLength`, `PdfSvgPresentationProps`, `PdfSvgTransform`, `PdfSvgTransformOperation` |
@@ -0,0 +1,185 @@
1
+ ---
2
+ title: "Registry and render result"
3
+ description: "The typed #pdf server module, runtime dispatch, and completed render conversions."
4
+ url: "https://nuxt-pdf.lupinum.com/docs/reference/registry"
5
+ route: "/docs/reference/registry"
6
+ locale: "en"
7
+ section: "Documentation"
8
+ collection: "docs"
9
+ source: "ginko-content"
10
+ ---
11
+
12
+ # Registry and render result
13
+
14
+ > The typed #pdf server module, runtime dispatch, and completed render conversions.
15
+
16
+ Nuxt generates an inspectable `#pdf` module from the discovered templates. It is
17
+ a server-only module for Nitro code and is typed from each SFC's props. Do not
18
+ import it from a client component or other browser code.
19
+
20
+ ```ts
21
+ import { pdf, renderPdf, pdfTemplateKeys } from '#pdf'
22
+ ```
23
+
24
+ ## pdf
25
+
26
+ `pdf` is an object keyed by template name. Property access infers each SFC's
27
+ props. Every value has exactly three public members:
28
+
29
+ ```ts
30
+ interface PdfTemplate<Props extends object> {
31
+ readonly key: string
32
+ resolveMetadata(props: Props): {
33
+ title?: string
34
+ filename?: string
35
+ language?: string
36
+ }
37
+ render(props: Props): Promise<PdfRenderResult>
38
+ }
39
+ ```
40
+
41
+ The handle does not expose the compile-time definition, preview data, source
42
+ file, or a second preview render method.
43
+
44
+ ```ts
45
+ await pdf.invoice.render({ invoice })
46
+ await pdf.report.render({ report })
47
+ ```
48
+
49
+ Nested template paths keep their slash keys (for example
50
+ `pdf['reports/monthly']`).
51
+
52
+ ## renderPdf
53
+
54
+ `renderPdf(name, props)` is the functional form. A **literal** template name
55
+ infers its props:
56
+
57
+ ```ts
58
+ await renderPdf('invoice', { invoice })
59
+ ```
60
+
61
+ A runtime string cannot be type-checked, so it requires the explicit
62
+ unknown-props escape hatch:
63
+
64
+ ```ts
65
+ await renderPdf(templateName, untypedProps, { unsafe: true })
66
+ ```
67
+
68
+ <warning icon="lucide:triangle-alert">
69
+ `{ unsafe: true }` does **not** validate the props; it only makes the loss of
70
+ static typing visible at the call site. An unknown template name still fails with
71
+ `PDF_TEMPLATE_NOT_FOUND`.
72
+ </warning>
73
+
74
+ `pdfTemplateKeys` is the array of discovered template names.
75
+
76
+ `getPdfTemplate(name)` returns that typed three-member handle for a literal name,
77
+ or `undefined` for an unknown name. Reach for it when you need resolved
78
+ `definePdf` metadata without rendering:
79
+
80
+ ```ts
81
+ import { getPdfTemplate } from '#pdf'
82
+
83
+ const template = getPdfTemplate('invoice')
84
+ const { title, filename } = template.resolveMetadata(props)
85
+ ```
86
+
87
+ `resolveMetadata()` evaluates the `title` and `filename` declared by
88
+ `definePdf`, and returns its `language`. It does not mount the component, so an
89
+ authored `PdfDocument` fallback is not part of this result.
90
+
91
+ `NuxtPdfError` and `PDF_ERROR_CODES` are also re-exported from `#pdf`, so
92
+ server code can branch on render failures without extra imports. See
93
+ [Errors and limits](/raw/docs/reference/errors-and-limits.md).
94
+
95
+ ## The render result
96
+
97
+ Both `pdf.name.render(props)` and `renderPdf(...)` resolve to a
98
+ `PdfRenderResult`. The document is rendered once; every conversion reuses that
99
+ completed, immutable byte buffer:
100
+
101
+ ```ts
102
+ const result = await pdf.invoice.render({ invoice })
103
+
104
+ result.metadata // frozen title, filename, and language for this render
105
+ await result.toUint8Array() // Promise<Uint8Array>
106
+ await result.toBuffer() // Promise<Buffer>
107
+ await result.response() // Promise<Response>
108
+ ```
109
+
110
+ `result.metadata` is the frozen `title`, `filename`, and `language` resolved for
111
+ this render: `definePdf` values win when present, otherwise authored
112
+ `PdfDocument` fallbacks. `title` and `language` describe PDF Info fields;
113
+ `filename` is response/download metadata and is not written into PDF Info.
114
+ `result.diagnostics` is one frozen object shared with the development preview:
115
+
116
+ | Field | Meaning |
117
+ | --- | --- |
118
+ | `durationMs` | Wall time for the whole public render, including metadata evaluation |
119
+ | `byteLength` | Exact output byte count |
120
+ | `pageCount` | Number of rendered pages |
121
+ | `passes` | Layout passes used (`1` normally, more for a TOC) |
122
+ | `layoutWarnings` | Frozen, structured warnings for layout that rendered but needs attention |
123
+ | `registeredFontFaces` | Frozen family/weight/style facts; never source bytes or paths |
124
+
125
+ Diagnostics contain no document content, props, or resource URLs. An
126
+ application can send them to its metrics layer.
127
+
128
+ `layoutWarnings` is empty for a healthy layout. Nuxt PDF currently reports
129
+ `PDF_UNBREAKABLE_NODE_OVERFLOW` when a non-fixed node cannot wrap and is taller
130
+ than the page's usable content height. The warning identifies the page and
131
+ primitive and includes both heights in points, without copying text or ids from
132
+ the document. Allow the node to wrap or make it small enough to fit on one page.
133
+
134
+ ## Development and production boundary
135
+
136
+ The development preview keeps `sampleData`, named `scenarios`, and the relative
137
+ source file outside the public template handle. It calls the same public
138
+ `render(props)` method as application code and displays that completed result.
139
+ There is no separate preview renderer or second document render.
140
+
141
+ Editing a template rebuilds its registry and refreshes the document with its
142
+ diagnostics. The preview keeps the selected scenario.
143
+
144
+ In a production build the SFC transform reconstructs the render definition from
145
+ only `title`, `filename`, `language`, and `maxPasses`. `sampleData` and
146
+ `scenarios` are structurally omitted before Nitro bundles the template; they are
147
+ not public handle properties and are not merely hidden behind runtime checks.
148
+ The development preview data and routes are also absent. Packed-consumer checks
149
+ verify this boundary and keep the renderer and template SFCs out of the client
150
+ output.
151
+
152
+ Metadata is hoisted: inline values and imports are supported, while references
153
+ to bindings declared locally in `<script setup>` are compile errors. Imported
154
+ preview-data modules must be side-effect-free so their unused production imports
155
+ can be eliminated.
156
+
157
+ ### response(init)
158
+
159
+ `response()` returns a `Response` with `content-type: application/pdf`, the
160
+ exact `content-length`, and a sanitized, encoded-length-bounded
161
+ `content-disposition` filename:
162
+
163
+ ```ts
164
+ await result.response({
165
+ disposition: 'inline', // 'attachment' (default) | 'inline'
166
+ filename: 'invoice.pdf', // sanitized before writing the header
167
+ headers: { 'cache-control': 'no-store' },
168
+ })
169
+ ```
170
+
171
+ | Field | Type | Description |
172
+ | --- | --- | --- |
173
+ | `disposition` | `'attachment' \| 'inline'` | `content-disposition` type; defaults to `attachment` |
174
+ | `filename` | `string` | Download filename; sanitized before use; defaults to template metadata or `document.pdf` |
175
+ | `headers` | `HeadersInit` | Extra response headers merged in |
176
+ | `status`, `statusText` | `number` / `string` | Standard `ResponseInit` fields |
177
+
178
+ Caller-provided `content-type`, `content-length`, and `content-disposition`
179
+ headers are replaced with the truthful values from the completed result.
180
+
181
+ ## Regenerating the registry
182
+
183
+ The registry is written during module setup and regenerated whenever templates
184
+ change in development. If `#pdf` imports appear untyped in your editor, run
185
+ `nuxt prepare` once to refresh the generated types.
@@ -0,0 +1,53 @@
1
+ ---
2
+ title: "Standalone build and runtime"
3
+ description: "Production registry generation and Node runtime exports outside Nitro."
4
+ url: "https://nuxt-pdf.lupinum.com/docs/reference/standalone"
5
+ route: "/docs/reference/standalone"
6
+ locale: "en"
7
+ section: "Documentation"
8
+ collection: "docs"
9
+ source: "ginko-content"
10
+ ---
11
+
12
+ # Standalone build and runtime
13
+
14
+ > Production registry generation and Node runtime exports outside Nitro.
15
+
16
+ ## Build options
17
+
18
+ `@lupinum/nuxt-pdf/build` exports the `buildPdfRegistry` function and the
19
+ `BuildPdfRegistryOptions` type. The function resolves to `Promise<void>`.
20
+
21
+ | Option | Type | Behavior |
22
+ | --- | --- | --- |
23
+ | `rootDir` | `string` | Required application root containing `pdfs/`. Relative to the working directory. |
24
+ | `outDir` | `string` | Required dedicated output directory inside `rootDir` and outside `pdfs/`. Relative paths use `rootDir`. An existing directory must carry Nuxt PDF's ownership marker. |
25
+ | `fonts` | `readonly PdfFontDeclaration[]` | Defaults to no custom fonts. Sources resolve under `pdfs/fonts/`. |
26
+ | `limits` | `PdfLimitsOptions` | Existing render and image-admission limits. Omitted fields use the engine defaults. |
27
+ | `remote` | `RemoteAssetOptions` | Existing remote-image policy. Denied by default. |
28
+
29
+ The build rejects unknown options, missing templates, invalid resources, invalid
30
+ templates, and type errors. A successful build emits `index.mjs`, `index.d.mts`,
31
+ and the declarations needed for inferred props. It uses Vue's type checker at
32
+ build time; consumers use ordinary TypeScript. See
33
+ [standalone rendering](/raw/docs/guides/standalone-node.md) for the procedure and
34
+ output-directory replacement rules.
35
+
36
+ ## Server exports
37
+
38
+ `@lupinum/nuxt-pdf/server` is a Node-only production entry. It has no Nuxt virtual
39
+ imports or source compiler. Generated registries use `createPdfTemplate` to bind
40
+ a compiled component to its admitted resources, then `createPdfRegistry` to
41
+ assemble named template handles. Application code should use the generated
42
+ registry instead of constructing this resource configuration manually.
43
+
44
+ `PdfRegistryEntries` describes the readonly named handles. `PdfRegistry`
45
+ describes their runtime dispatch. `PdfComponentProps` extracts authored Vue
46
+ props. `PdfDefinition` describes compile-time metadata. `PdfTemplate` and
47
+ `PdfRenderResult` describe the public handle and completed bytes. The entry
48
+ also exports `usePdfPageNumbers`, `NuxtPdfError`, `PDF_ERROR_CODES`, and
49
+ `PdfErrorCode` with their existing behavior.
50
+
51
+ No export sends email, stores a document, authenticates a caller, or selects a
52
+ backend provider. The runtime preserves the current Node requirements and
53
+ [resource limits](/raw/docs/reference/errors-and-limits.md).