Skip to main content

Conformance & philosophy

The compatibility approach, what is deliberately not claimed, and why the narrow contract is the product.

Nuxt PDF makes a behavioral compatibility claim for a small, tested corpus, not a claim of full React PDF API or test-suite parity. The honesty of that boundary is part of the product. You can trust the documented behavior because an executable fixture protects it, and you can trust the exclusions because they are stated rather than discovered in production.

The compatibility approach

Nuxt PDF drives React PDF's framework-neutral layout, font, and serialization packages at exact pinned versions. Compatibility is defined against those pins and must be re-evaluated when any of them changes.

The evidence is a paired-fixture strategy. For each claim, the same renderer-agnostic data is rendered through both React PDF and the Vue renderer, and the outputs are compared on the axis that matters:

  • extracted text and page counts, for content;
  • laid-out box geometry (React's own onRender tree is the oracle), for layout;
  • annotation and catalog reads via pdfjs, for links, notes, metadata, and outlines; and
  • thresholded page-by-page raster comparison against reviewed baselines, for genuinely visual claims.

If the two renderers diverge, that divergence is at the renderer boundary. The suite detects this divergence. The tested corpus spans pagination, text, images, styles and layout, annotations and metadata, SVG drawing, the table-of-contents multi-pass loop, and the local and opt-in-remote resource boundaries.

The Nuxt production boundary is executable too. The public template handle is closed to key, resolveMetadata, and render; the development preview uses that same render result through a separate internal fixture sidecar. A production fixture places unique canaries in sampleData and scenarios, then recursively scans the emitted Nitro server artifact to prove those values and preview-only APIs were structurally removed. A separate assertion proves the server-only renderer and template modules did not enter the client bundle.

Deliberate divergences

A few behaviours intentionally differ from upstream React PDF, because the alternative is worse:

  • Table-of-contents destinations resolve to a section's first page, not its last. React PDF's last-writer-wins destination table points a page-spanning section at its last page; Nuxt PDF anchors it at the first, which is what a reader expects from a contents entry.
  • Dynamic page-number footers render at correct page-bottom geometry even when a lineHeight reaches them. Upstream drops such footers; Nuxt PDF keeps them. It does not apply a lineHeight multiplier to dynamic text, because the upstream engine re-resolves dynamic-node styles during pagination and cannot carry an absolute line height through. Apply lineHeight to static PdfText instead.
  • Explicit SVG zeroes keep SVG meaning. The pinned serializer uses truthy fallbacks for a few resolved values, so Nuxt PDF repairs those values before paint: zero fill opacity stays transparent, zero stroke width paints no PDF hairline, and the supported zero gradient coordinates stay zero.

These divergences are protected by Vue-only geometry and raster regressions.

What is deliberately not claimed

These are scope decisions, not bugs:

  • Full React PDF component, hook, browser-helper, or test-suite parity.
  • React runtime compatibility, or asynchronous / non-scalar dynamic callbacks.
  • Browser-side or edge rendering. The engine is for Node servers only.
  • Nuxt 3, Node 20, or versions outside the supported table.
  • Browser CSS, HTML printing, a PDF stylesheet compiler, or paged-media CSS.
  • A first-class table engine, charts, forms, signing, editing, or PDF merging. A table of contents is authored from ordinary components; there is no TOC component or automatic heading collection.
  • Tagged PDF, PDF/UA, or archival/accessibility compliance profiles.
  • Deterministic PDF bytes across operating systems or viewers.
  • Authenticated remote fetches, request headers, credentials, remote fonts, or SSRF protection beyond exact-prefix allowlisting. Opt-in allowlisted remote images are claimed.
  • SVG image files as a source, SVG Marker, alternate gradient coordinate systems/transforms/inheritance, preserveAspectRatio modes, and radial gradient inner radius (fr). SVG drawing primitives are otherwise claimed.
  • Multi-pass resolution of anything other than destination page numbers. Documents whose geometry depends on the numbers they print fail closed with PDF_LIMIT_EXCEEDED rather than being forced to converge.

Why the narrow contract is the product

An alpha that claimed everything and delivered some of it would be untrustworthy in a way that document generation cannot support. The failure shows up in a customer's invoice, not a test run. Nuxt PDF instead ships a boundary you can reason about: a short list of things it does, each backed by a paired fixture, and an explicit list of things it does not. Growing the first list means adding a fixture first.

The canonical record

This page summarizes the approach. The repository contains the exact tested boundary, including every fixture, pinned engine version, and non-claim:

When this documentation and the code disagree, the code is authoritative. The documentation has a defect.