Pulp EngineDocument Rendering
Get started

Template Format Compatibility

How Pulp Engine versions the template definition format, what compatibility you can rely on across upgrades, and how to pre-flight stored templates before upgrading a server.

The format generation is distinct from a template’s version field. version is the content semver — it bumps every time you edit a template. formatVersion is the format generation — it identifies which generation of the definition format the JSON document is written in.

Governed AI narrative (Wave 77, unreleased)

Format generation remains 1. aiNarrative is an additive content-node type; existing templates need no migration. Older strict servers reject it, so upgrade before saving narrative templates. The node includes required static instruction, 1–25 explicit facts and a required text fallback; generation controls are optional. Rendering preserves fallback whenever AI cannot run. HTML/PDF, DOCX and PPTX render literal styled text; CSV/XLSX omit the block and make no AI calls. The aiNarratives request option and dry-run narrative fields are additive API changes.

Template data sources (Wave 69, unreleased)

Format generation remains 1. Optional root dataSources and source connection, JSON Pointer select, JSON format, and pagination fields are additive. Older strict servers reject these fields; upgrade the server before saving templates that use them. Existing push-only templates retain their behaviour. Pulling precedes mappings and validation in every output format, including PDF streams. Referenced-template sources retain the object contract; root sources also accept arrays. Omitted render data now means {}. Connections are environment-local and tenant-scoped; portable templates refer to names rather than connection IDs or secrets.

Long-document typesetting (Wave 62, unreleased)

Format generation remains 1. Node/group runningValues, rich-text note inlines and renderConfig.notes are optional additions. Existing definitions need no migration; older strict readers may reject the new fields and inline type. Nineteen frozen legacy definitions produce byte-identical HTML to the Wave 61 production image. The deprecated-looking text variant name footnote remains stored unchanged and still means small-print sizing.

PDF resolves running markers after page flow; HTML preview uses first values. Word STYLEREF source markers use transparent clipped frames because Word ignores vanished source runs. Native Word notes use one entry per reference and Word’s own numbering; notes settings apply to HTML/PDF/PPTX. PDF footnotes are linked lists, not page-bottom reflow. PowerPoint values are per slide with approximate attribution on automatic overflow. CSV/XLSX omit notes and running chrome. See the API guide for policies and defaults.

Charts and icons (Wave 61, unreleased)

Format generation remains 1. The eight new chart enum values, their optional fields, the icon node and table-column icon options are additive; existing definitions require no migration. Older strict servers reject these new enum values, node types and fields.

Feature HTML / PDF DOCX PPTX CSV / XLSX
Eight extended charts Shared inline SVG Shared SVG plus PNG fallback PNG from the same SVG Skipped
Icon node Bundled inline SVG, accessible alt or decorative PNG and label PNG and label Skipped
Table icon column Bundled inline SVG, optional value text PNG, optional value text Formatted value text Source value

Icon names are pinned to Lucide 0.577.0. Data selects allowlisted names and never supplies SVG. Unknown values render a configured fallback or nothing. The new types share the existing chart resolver; no legacy private resolver copies were reintroduced.

Pivot matrices (Wave 60, unreleased)

Format generation remains 1. Nested column dimensions (up to three total), column subtotals, date buckets, measure keys, calculated measures, ranking and new show-as modes are optional additions. Older strict readers may reject the new keys. Existing pivots without matrix features retain their HTML/CSV bytes. An explicit sort on an inner row dimension, previously ignored, now takes effect; unset inner sorts inherit the preceding direction. Base keys default to measure_1, measure_2, etc.; assign explicit keys before referencing them so reordering does not change expression/ranking meaning. Fiscal years are named by their end year. The frozen matrix starter extends the compatibility corpus.

Accessible output (Wave 47, unreleased)

Format generation remains 1. Chart alt, description, decorative, dataTable and image decorative are optional additions; existing definitions require no migration. Older strict readers may reject these keys. Charts gain accessible SVG metadata, table/pivot headers gain scopes, and decorative images lose assistive descriptions. All 28 default starter packs retained identical PDF pixels across 46 pages at 108 dpi. See per-format support and verification. PDF/UA identification remains deferred after the required spike failed.

Spreadsheet exports (Wave 27, unreleased)

Format generation 1 adds optional table/pivot spreadsheet settings and renderConfig.xlsx/renderConfig.csv defaults. These fields affect XLSX/CSV extraction only; HTML, PDF, DOCX and PPTX output is unchanged. Unknown option keys are rejected. Native XLSX now preserves leading-zero/long identifiers, types formatted numbers and dates, includes enabled footers and uses friendly names in document order. For legacy cells, set renderConfig.xlsx:{layout:'data',cellTyping:'text'}. CSV without new options keeps the existing comma/CRLF bytes and no BOM. The editor alone starts its download dialog with BOM enabled. Existing renderCsv() callers retain single-table text output; use renderCsvExport() for binary ZIP/TSV exports.

The promise: additive-only within a format generation

Within format generation 1 (every release to date), schema changes are additive only:

  • New node types, new optional fields, and new enum values may be added.
  • Existing fields are never removed, renamed, or re-typed.
  • A definition that parsed under an older server parses under every newer server in the same generation.

This is enforced in CI by a frozen fixture corpus (apps/api/src/__tests__/fixtures/compat/ — including a production seed template from v0.18.0 and representative starter-pack builds). Those files are committed once and never regenerated; compat-fixtures.test.ts asserts they parse under the current save-boundary schema on every build. A schema change that breaks any frozen fixture cannot merge.

The reverse direction is not promised: a template that uses a node type introduced in v0.85.0 will be rejected by a v0.60.0 server. Downgrading a server below the version that authored a template is unsupported.

formatVersion semantics

Value Meaning
absent Format 1. Every definition saved before v0.85.0 omits the field; every format-1 reader treats absence as 1.
1 Format 1, stamped explicitly. The API stamps formatVersion: 1 at the save boundary (create and update) from v0.85.0 onward, so all newly-saved definitions carry it.
2+ Reserved for a future breaking format change. A format-1 server rejects such documents loudly (HTTP 400 with a formatVersion issue) instead of silently misreading them.

Notes:

  • The stamp covers every save path — hand-authored API calls, the visual editor, starter packs, and AI generation all pass through the same POST /templates / PUT /templates/:key validation and stamping.
  • Version restore is a faithful clone. Restoring a pre-v0.85.0 version reproduces its stored bytes, including the absent formatVersion — which still means format 1. Restore does not rewrite history.
  • Sending formatVersion: 1 yourself is valid and equivalent to omitting it.

Restore-on-drift behaviour

POST /templates/:key/versions/:version/restore re-validates the stored historical definition against the current schema before restoring. If a historical version predates the additive-only enforcement and no longer conforms, the restore fails with 400 Stored Version Invalid and the template’s history is left untouched. The error body lists the exact issues. Because format changes are additive-only, this should not occur for any version saved on v0.18.0 or later; it exists as a fail-closed guard.

Pre-flighting an upgrade

Before upgrading a server, you can validate exported/stored template JSON offline with the CLI — it applies the same Zod schema the API enforces at the save boundary:

# Validate one file or a directory of definitions (no API required)
pulp validate ./templates
pulp validate ./my-template.json --strict

A green pulp validate from the new release’s CLI against your stored definitions means every one of them will load on the new server.

Where the schema lives

Artifact Role
@pulp-engine/template-model TypeScript interfaces (TemplateDefinition, node types).
@pulp-engine/template-schema The runtime Zod schema — single source of truth, used by the API save boundary, the CLI validate command, and the editor’s starter-pack parity test.
apps/api/src/__tests__/fixtures/compat/ Frozen cross-generation corpus; grows via node scripts/freeze-compat-fixture.mjs <pack-id> <fixture-name>.

Wave 1 additive fields and output fidelity

Format generation stays 1. Optional renderConfig.pagination, renderConfig.metadata and renderConfig.bookmarks do not invalidate legacy definitions. Absence of pagination preserves previous pagination behavior; new editor-created templates opt in at creation. The policy affects printed HTML/PDF and DOCX, not slide or tabular outputs. Per-node hints take precedence.

DOCX now resolves uploaded, inline and policy-permitted remote images, evaluates rich-text bindings, and caches TOC heading titles. Charts/barcodes embed vectors with PNG fallbacks. WebP and unknown formats remain unsupported and produce warnings; positioned nodes, sticky headers and sparklines degrade with warnings. Legacy stored SVG assets remain blocked. Both DOCX renderer entry points return { buffer, warnings }; integrations using the internal renderer must unwrap buffer. The HTTP binary response stays compatible.

HTML now includes a title even without metadata. Header/footer title tokens therefore show the template name by default. PDF post-passes preserve producer, outline and tagging information, and streaming TOCs receive page-number stamps.

Numeric semantics and formatting (audit Wave 2)

The format generation remains 1. Locale and numeric settings are additive. The intentional defaults change ISO currency digits (JPY 0, BHD 3), exact sums (0.1+0.2 gives 0.3), positive decimal ties (round(1.005,2) gives 1.01), and negative ties (round(-2.5) gives -3). Use currencyDigits:"fixed2" and numeric.arithmetic:"float" for legacy behavior. Existing date presets remain; valid custom patterns now work with date, and invalid ones still fall back. Working arithmetic has 34 digits; numeric outputs have JS-number precision of about 15 significant digits. JEXL field mappings still use float arithmetic. See formatting and rounding reference.

Format Locale and zone New formatting
HTML/PDF Shared effective locale; document language and page-chrome dates Localized text
DOCX Shared locale; default run language Localized text
PPTX Shared locale; run language is deferred Localized text
CSV Shared locale Localized plain text
XLSX Shared locale; wall-clock date fields Numeric/date cells for mappable formats; other formats are text

Schedules fall back to their cron zone when render/template zone is absent. Excel retains raw numbers and uses its own rounding when displaying numFmt.

Expressions and report globals (audit Wave 3)

The format generation remains 1. Logic, decimal math, string, array and date helpers are format-agnostic; nl2br emits HTML breaks only for HTML/PDF and retains literal newlines in Office/CSV. A template using a new helper fails on an older server with Missing helper. See the Expression reference.

Bare {{date}}, {{number}}, {{currency}} and {{count}} now return the current object’s own field; calls with arguments retain helper behavior. Numeric helper equality coerces numeric strings ("007" equals 7); structured equality stays strict unless valueType is explicit. The original eight condition operators retain legacy behavior. New operators and optional caseInsensitive/valueType fields are additive and require an updated server. Raw JEXL equality retains its own coercion rules.

Report globals are separate from payload fields. Header/footer date tokens use the captured render clock when now is supplied or a locale is explicit; otherwise legacy date-token behavior is retained. Fixture snapshots now use a fixed default clock; a fixture or case can override it. Durable job clocks survive restart, but interrupted worker resumption remains outside this change and existing abandonment policy still applies.

Font registry (format 1 additive)

renderConfig.fonts and defaultFont are optional. Older templates remain valid; the frozen brand-fonts-wave4.json fixture records the additive shape. HTML snapshot baselines see the new explicit body stack 'Liberation Sans', Arial, sans-serif.

Output Typography support
PDF / HTML Referenced uploaded TTF/OTF/WOFF/WOFF2 embedded; PDF uses installed Docker script fallback fonts. Viewing HTML on another host uses that host’s fallback fonts.
DOCX Regular TTF/OTF embedded as obfuscated font parts; Word synthesizes bold/italic. WOFF/WOFF2 require viewer fonts. Defaults map to document styles.
PPTX Family names in runs/theme, with one font_not_embedded warning per referenced registered family; viewer must install fonts.
XLSX / CSV Font registry is not applicable; XLSX typography relies on viewer fonts.

Chrome headers/footers remain outside the font registry until FA-35. Font aliases should match internal family names for reliable Office rendering.

Item scopes and schema authoring (audit Wave 5)

Format generation remains 1. Optional itemAlias on repeaters and tables is additive; item-scopes-wave5.json freezes its shape. Old definitions retain item spreading. New aliases require an updated server and use a shared reserved-name validator. The API’s document-tree OpenAPI field remains intentionally untyped; Zod validates the full tree, the TypeScript SDK imports the model, and the Python SDK carries the document object without a new transport field.

All renderers now carry actual Handlebars loop data frames (@index, @number, @first, @last, @count, @item, @parent), retaining legacy plain @ keys for path conditions and column keys. Inline each delegates to the built-in and preserves block parameters, object keys and else branches. @root stays merged. A templateRef using field mappings starts a new frame (structured cloning drops symbol metadata). XLSX row numbers remain numeric cells.

Schema authoring preserves unknown/root keywords and primitive items; no schema format migration is needed. Inference and imports are reviewed before applying, and merge adds properties without rewriting existing constraints.

Chart axes, formats and captions

PDF and HTML use the same inline chart SVG; DOCX embeds that SVG with a high-resolution PNG fallback and PPTX rasterizes it through resvg. Axes, references and formatted labels share one data resolver and layout across those formats, including combo line overlays. CSV/XLSX do not emit chart nodes. DOCX/PPTX captions are editable native text. Subtitle/footnote bands remain inside the configured HTML/editor chart height.

Rendering corrections: negative bars now extend from zero, stacked bars diverge and areas close to zero. With no axes or format fields, positive chart geometry is preserved byte-for-byte. Line/area charts with showDataLabels: true now add the requested labels (previously ignored); their existing geometry is unchanged. Existing positive charts otherwise keep the frozen legacy SVG output. Axis layout is opt-in; new palette and report starter-pack Cartesian charts enable it.

Asynchronous output formats

POST /render/jobs supports PDF, HTML, CSV, XLSX, DOCX and enabled PPTX, using the same format renderers, hooks and options as synchronous output. Each item can select version or label, bucket key and a CSV/XLSX tableId. Optional callbacks and separate binary downloads are available for every format. The deprecated async routes remain PDF/DOCX only.

Output defaults and per-call render options (Wave 11)

Format generation remains 1. Optional renderConfig.output = {filename?, disposition?} and renderConfig.watermark = {text, opacity?, color?} are validated strictly. Download filenames support the same plain Handlebars expressions and mapped data as document metadata. Request options.filename, .disposition, .margins, .metadata and .watermark override those defaults without changing the saved template. Existing locale objects and string locale overrides retain their semantics.

Option PDF HTML DOCX PPTX XLSX CSV
Filename/disposition Yes, buffered and streaming Yes Yes Yes Yes Yes
Margins Print CSS and dispatcher Screen padding Section margins Ignored Ignored Ignored
Metadata HTML title and PDF Info pass Escaped title/meta Office core Office core, including keywords Office core Ignored
Text watermark Fixed rotated text on each printed page Fixed rotated text Behind-text VML in default header Shared slide layout/master text Centered print header Ignored

PDF metadata and TOC post-passes buffer within the worker before streaming frames. DOCX uses VML because the installed docx Textbox API omits fill controls; text opacity is represented as a tint on white paper. Word and LibreOffice visual verification remains a release check. PPTX font availability still depends on the viewing machine, as documented in Wave 4.

Wave 12 data shaping additions

dataView on tables, repeaters, charts and pivots, and scope/label on field mappings are additive. Unset views preserve existing order. Unset mapping scope continues to read the original payload; only explicit adapted scope or per-item [] targets read earlier results. Template-reference mappings use the same rules. No format-version migration is required. Calculations and row views apply consistently to HTML/PDF, DOCX, PPTX, CSV and XLSX; existing pivot support limits still apply. Numeric aggregates share decimal extraction with Handlebars helpers, including nested fields.

Wave 13 rich tables

Format generation stays 1. Optional column expression, cell, cellType, typed option blocks, visibility and overflow fields, table/pivot grid and layout fields, and table showHeader are additive. The frozen table-rich-cells-v0.87.json fixture protects their save-boundary shape.

Templates without these fields keep their existing output rules, including format-specific border defaults and header display. Explicit showHeader:true, repeatHeader:false displays a single non-repeating HTML header. DOCX column-over-row style precedence, background shading and percentage widths relative to the containing column are intentional behavior fixes; review existing Word layouts that depended on the old behavior. PowerPoint reports table_cell_degraded when an image, barcode or sparkline cell becomes text.

Wave 15 conditional formatting

styleRules, visibleWhen, table rowStyleRules, column/measure cellStyleRules and cellVisuals, and measure applyRulesTo are optional, additive format-generation-1 fields. No migration is required. Older strict servers reject templates containing these fields; upgrade the server before saving or rendering them. SDK endpoints and opaque definition payloads do not change. Templates without rules retain byte-identical HTML and XLSX cell values/styles in the pre-wave comparison checks. Rules accept literal NodeStyle keys, while native formats retain their documented mapped subset.

Wave 16 page chrome and numbering

Optional renderConfig.pageChrome, renderConfig.pageNumbering and section pageNumbering are additive format-generation-1 fields. No migration or new endpoint is needed. Older strict servers must be upgraded before saving these fields. Structured chrome/numbering reject legacy HTML headers and footers; conversion is explicit and undoable in the editor. Frozen page-chrome-wave16.json protects the new save shape. Templates without the new fields retain their legacy HTML and section-flattening behaviour.

Wave 18: grouping and record pagination

Format 1 adds TableNode.groups (1-4 levels), groupKeyColumns, column aggregate, RepeaterNode.group, and RepeaterNode.itemPagination. Old templates need no migration. Templates without these fields retain their HTML output; the frozen compatibility corpus remains valid. {{#groupBy}} remains available, while structural grouping supersedes it for banded reports.

Format Group bands and totals Pagination
HTML Full CSS hints; browser preview has no PDF page-field post-pass
PDF Full Keep together, page/odd-page breaks, repeated group/banner headers, numbering restarts
DOCX Native spanning rows and totals Keep/row breaks, repeated root headers, next/odd-page sections and restart; leading-child repeat is unsupported
PPTX Bands and totals Root table group and repeater breaks start slides; keep together, repeated headers, parity and numbering reset are ignored
XLSX Numeric totals, merged bands, outlines No printed page grouping; outline levels collapse details to subtotals
CSV Details in group order; optional group-label columns Bands and pagination omitted

DOCX section boundaries nested inside tables or columns degrade to a plain page break with a render warning. PDF keep-together is best effort for content larger than a page. Legacy HTML page headers/footers in record-flow PDFs are converted to text bands, preserving page fields and supported text styling; use structured pageChrome for images, independent left/center/right slots and rich chrome. PDF duplex blank pages have no header/footer and count toward the preceding record’s total. TOC numbers remain absolute when record numbering restarts.

Wave 19 themes (formatVersion 1)

kind, renderConfig.theme, renderConfig.themeRef and styleRef are optional additive fields. An absent kind is a document. Existing unthemed templates retain their rendering paths and variant fallbacks. Theme-resolved styles are applied to a clone; saved templates and referenced specimens are not rewritten by rendering. Tokens in ordinary text content remain literal text.

HTML emits optional token CSS variables and named-style class hooks. DOCX uses real paragraph styles with basedOn, and direct formatting only for inline overrides; contextual paragraph styles preserve heading/variant defaults when an explicit style is chosen. Table styles are direct formatting. PPTX records theme fonts and uses flattened effective styles; recipients still need the fonts installed. Theme chart palettes affect palette-driven chart types, while heatmap gradients and waterfall semantic colours remain unchanged. CSV/XLSX retain their existing presentation defaults.

The frozen starter-invoice-themed-v0.86.json fixture pins a themed invoice. Verification compares legacy fixtures and pre-theme starter packs against the pre-Wave-19 renderers: HTML byte equality and Office package-part equality after normalizing creation/modification timestamps and generated relationship IDs, and decoding Word font-obfuscation keys. ZIP timestamps are packaging metadata and are not a rendering contract. Native Word/LibreOffice visual opening remains a release check; XML/package assertions do not establish that visual check.

Wave 20 charts and KPI cards

Chart colours/legend, seriesField/aggregation, stackedArea, gauge bands/targets and the kpi node are additive on formatVersion 1. Older servers reject the new fields or node/chart types; upgrade the render server before saving definitions that use them. Existing definitions retain byte-identical SVG, except the intentional fixes for multi-series showLegend:false and shared-scale combo charts containing only lines. CSV/XLSX ignore KPI cards. rgba chart colours normalize to opaque hex. Aggregated Top-N operates on categories and numeric count excludes non-numeric observations. Existing fixtures were not regenerated.

Wave 21 additive data and binding fields

Format 1 adds optional dataOptions (applySchemaDefaults, schemaDefaultWhen, coerceTypes, strictBindings), mapping defaultWhen, table-column nullText, and node hideWhenEmpty. With these options absent, preparation and output retain existing behavior. exists semantics are unchanged. The frozen null-handling-v0.87.json fixture covers the new fields.

Feature HTML/PDF DOCX PPTX CSV XLSX
Defaults, coercion, mapping defaults Yes Yes Yes Yes Yes
Empty-cell text Yes Yes Yes Empty cells Empty cells
Blank suppression Yes Yes Yes Table discovery Table discovery
Strict bindings Yes HTML preflight HTML preflight Table bindings Table bindings

Binding diagnostics are additive dry-run fields. Legacy /render/validate responses remain unchanged unless callers request binding checks. These diagnostics describe the shared HTML expression walk; custom helper bodies and sampled array tails are not inspected.

Wave 22 statement totals and pagination

Format 1 adds column running/percentOf, aggregation distinctCount/median, pivot measure showAs and table pagination. All options are strict and optional. Derived values are shared across HTML/PDF/DOCX/PPTX/CSV/XLSX; percentages are ratios and default to percent formatting. PDF alone calculates physical page totals, brought/carried balances and continuation text. DOCX implements header omission/repetition, row protection and the final footer; HTML emits layout hints, while PPTX warns about PDF-only options. CSV/XLSX retain table data without continuation bands.

Three intentional fixes can change an old template’s output: dotted helper fields now resolve nested values (own literal-dot keys retain priority); pivot count includes non-null text instead of leaving those cells blank; repeatHeader:false keeps the first header, including headerRows, instead of removing it in HTML/PDF. Definitions without pagination or the legacy non-repeating-header setting retain identical HTML and DOCX document XML; 41 existing fixtures/starter packs were compared without regeneration. New table creation defaults to footerMode:'lastPageOnly'; saved definitions are not rewritten.

Page totals require protected rows, cannot share a repeated grand-total footer, and do not support repeating root group headers. Their per-call manifest stays in the parent render process. Stamped PDF streams intentionally use a buffered fallback; ordinary streams are unchanged. See the editor guide and verification notes for support, fonts and measured cost.

Preview node anchors (Wave 23)

POST /render/preview/html?annotate=true and /render/preview/pdf?annotate=true add a hidden link index and block destinations for the editor’s page map. Ordinary preview requests and all production render routes omit these annotations. The collector is limited to 5,000 occurrences, marks truncation, and ignores nodes inside template references. Existing arbitrary HTML ids are preserved; those blocks inherit navigation from their enclosing block. Heading ids now escape attribute characters, correcting malformed markup for node ids containing quotes or angle brackets; normal heading ids and unannotated output remain unchanged.

Rich text and formatted payloads

Wave 24 is additive within format 1. Frozen legacy templates still parse and retain byte-identical HTML. DOCX list/style fixes and PPTX soft breaks intentionally improve Office output. Native desktop Word/PowerPoint visual verification remains outstanding; package XML checks cover the mappings.

Feature HTML / PDF DOCX PPTX CSV / XLSX
Strike, super/subscript, highlight, fonts Native tags/CSS Native runs Native runs Omitted
Alignment, spacing, indent, heading/quote Native blocks/CSS Native paragraphs/headings Native paragraphs/runs Omitted
Four-level lists Native; old shorter lists preserve historical defaults Per-render numbering registry Native bullets/numbering Omitted
Legal numbering CSS counters Native legal numbering Arabic per level plus one warning per node Omitted
Formatted source (Markdown/HTML/text) Sanitized native content Native content Native content plus degradation warnings Omitted
Payload expressions Literal Literal Literal Omitted

For shorter HTML lists requiring matching numbering, set numbering explicitly. Font availability can still affect layout; select installed or bundled families. Bound markup is converted to allowlisted blocks with 200,000-character and 2,000-block caps. Missing/null/blank sources fall back or hide; non-string values fall back and warn.

Image fields and stable asset names (Wave 25)

fallbackSrc, objectPosition and boolean false for inherited hideWhenEmpty are additive within format 1. The existing data-path form of hideWhenEmpty remains supported. The asset helper resolves names/ids through tenant-scoped API metadata. Old templates retain their HTML output; the default Office contain fit now preserves aspect ratio instead of stretching.

Feature HTML / PDF DOCX PPTX CSV / XLSX
Sanitized library SVG Image/data URI SVG plus PNG fallback PNG Omitted
Fallback / hide Empty, unsafe and missing library sources Resolver fallback, optional misses Resolver fallback, optional misses Omitted
Cover and focal point CSS object-position Pre-cropped PNG Same pre-cropped PNG Omitted
Contain CSS aspect ratio Aspect ratio retained Aspect ratio retained Omitted

Remote URLs follow the remote-resource policy. HTML/PDF do not detect remote 404s for fallback. SVG live text depends on available fonts; outlines give stable logos. Legacy unsanitized SVG remains quarantined and WebP remains unsupported in Office output.

Plugin expressions

Templates calling plugin Handlebars helpers or JEXL functions require those plugins on every rendering server. Moving the template to a server without them produces an expression error. Plugin metadata is discoverable in capabilities; it does not embed the implementation in a template. Built-in-only templates retain their existing portability and model shape.

Wave 28 PDF output defaults

renderConfig.pdf is optional and strict: pdfa: "2b"|"3b", permissions and userPasswordPath. It cannot contain literal passwords or combine archival and security defaults. Request credentials live under options.pdf.security and are removed before worker dispatch. Existing templates remain ordinary PDFs unless opted in. Saved PDF defaults do not change HTML, DOCX, PPTX, CSV or XLSX.

TOC/page-chrome/watermark fallback fonts now embed OFL Liberation Sans instead of referencing unembedded Helvetica. The fonts have matching advance widths (guarded within 1 point), although PDF bytes and font resource names change. Unrepresentable watermark characters return a clear error. Numbered TOC streams buffer so stamping and page-count metadata are retained.

Schedule output options (Wave 31)

Schedule settings now accept six renderer formats, an optional format list, table selector and attachment/ZIP packaging. These are schedule API/storage fields, not template document fields, and do not change template formatVersion. Existing schedule rows have no output-options JSON and retain their single PDF/DOCX behavior (formats:null, tableId:null, packaging:'attachments'). PostgreSQL and SQL Server each add a nullable output-options column; old render artifacts and delivery DLQ entries remain readable. Deploy the migration before the new API. HTML outputs inline assets; multi-format rendering delivers nothing if any selected renderer fails.

Test API key watermark

A pe_test_ credential forces the test-use watermark in PDF, HTML, DOCX, PPTX and XLSX even with a valid commercial licence. User footers and template watermarks are retained. XLSX marks document metadata and printed sheet footers without adding data rows. CSV has no watermark. Upgrade isolated render workers before the API when adopting test credentials.

Wave 37: parameters and sub-reports

parameters, fiscal/week locale options, templateRef.label and templateRef.applyTargetContract are additive; formatVersion remains 1. Older servers with strict schemas reject these new fields. Parameter resolution and sub-report scope/contract semantics are shared across PDF, HTML, DOCX, PPTX, CSV and XLSX. Sub-reports inherit root parameters; independently bound child parameter declarations are deferred to the reusable-component contract (Wave 38).

URL-backed sub-reports in repeaters now interpolate per item, including item keys that shadow root keys. Static sources and plugins without instanceKey keep singleton behavior. Existing templates without declarations or contract flags retain their data namespace, mapping behavior and defaults. Legacy schedule parameter wrappers continue to work when the template has no declarations.

Shared components (Wave 38)

kind: "component" and templateRef.label are additive format-version-1 fields. The established document default and theme kind remain valid; the audit’s proposed report name maps to document. Existing columns and indexes remain, with additive PostgreSQL and SQL Server constraint migrations. A reference may select a version or label, never both, including nested branches and columns. Reference labels ignore traffic splitting. No pin follows current even when the root render defaults to prod.

Composition shares resolved definitions across HTML, PDF, DOCX, PPTX, CSV and XLSX. Component page settings are not inherited. Props reuse the existing inputSchema/fieldMappings contract; root report @params are inherited rather than rebound by a component. Validation reports missing pins and advisory props issues. Non-strict rendering keeps its established missing-reference behavior. The shared reference-key helper preserves exact-version keys and adds unambiguous key#label keys.

Master layouts (Wave 39)

Additive fields: template kind: "layout", layout: {templateKey, version?, label?}, layoutPolicy.lockedRenderConfig, section slot, and content node slot (name, optional label, description, required, allowedNodeTypes). Existing templates without a layout keep their rendering behavior. Slot names are unique within a layout and match ^[a-z][a-z0-9-]{0,31}$. Slots are valid only in layouts; chains and slots below conditional/repeater branches are rejected.

Format Layout behavior
PDF Merged content and page settings; header/footer repeats through the existing page chrome path.
HTML Merged content and preview chrome; standalone slots show empty placeholders.
DOCX Merged content and header/footer; existing section flattening applies. Standalone slots emit nothing.
PPTX Merged content and slide layout; documented Office fidelity limits apply. Standalone slots emit nothing.
CSV / XLSX Export child tables; inherited layout tables are excluded, including nested ones. Containers around inline slots remain traversable.

Inherited IDs receive a collision-safe lyt- prefix and meta.layoutOrigin; child IDs stay stable. Do not use effective definitions as new layout sources. Runtime layout refs use tenant-scoped, per-request/per-job memoization. Nested layouts, dynamic slots and applying a layout inside a templateRef remain deferred. Preserve the resolved layout revision alongside rendered archives when reproducibility is required.

Wave 43 additive page setup

Format version remains 1. PaperSize adds presets and a strict custom { width, height } object; margins add mirrored/gutter fields, RenderConfig adds PDF-only printProduction, and SectionNode adds pageSetup. Legacy free-string margins remain accepted unless mirroring/gutter needs physical arithmetic. Old section containers retain their continuous flow and single DOCX section. Old-template HTML changes only its formerly keyword-based page-size rule to explicit physical dimensions; 13 compatibility fixtures otherwise compare byte for byte. Existing PDF presets retain their baseline Chromium boxes and do not opt into CSS sizing unless a named section requires it. Exact DOCX ISO sizes and the landscape orientation correction are intentional geometry fixes.

Page decorations (Wave 44, unreleased)

Format generation 1 adds optional renderConfig.watermarks, background, stationery and pdfInserts. No migration is needed and definitions without these fields retain their previous markup. The older singular renderConfig.watermark is preserved. The frozen page-decorations-wave44.json fixture protects the additive schema contract.

Request options.watermark expands compatibly from text/colour/opacity to a single literal text or image mark with styles and page/layer controls. It adds to template marks. Template-only conditions/labels cannot be supplied by callers. See the per-format matrix for supported output and degradation warnings. New template keys do not affect XLSX/CSV; the existing XLSX text request watermark stays available.

Global languages (Wave 46, unreleased)

Format generation remains 1. Optional TemplateDefinition.i18n, RenderConfig.direction, BaseNode.lang/dir, logical start/end alignment and logical style spacing are additive. Existing templates need no migration. Current renderers retain physical left/right values; older strict readers may reject the new fields or enum values.

A frozen-clock comparison against pre-wave renderers found identical legacy DOCX and PPTX XML (22 parts each). HTML differs only in BASE_CSS table text-align changing from left to start, which is visually identical for LTR output; the legacy PDF pixels are identical. All frozen fixture checks pass. Explicit language/direction opts into native Office metadata and RTL behavior. Translation-only edits are included in diffs/merges and require no database migration. See verification and limitations.

Email HTML and raster images

Raster image output renders the completed PDF through PDF.js, preserving PDF page composition and decorations. It supports PNG, JPEG and WebP; TIFF remains deferred. PDF encryption does not encrypt image files.

Email HTML uses a 640px presentation-table wrapper (480–800 configurable), table columns, inline CSS, ordinary-flow positioned/sticky content and 2x PNG chart/barcode/plugin SVG images. TOCs and page-break nodes are omitted. Chart data is also exposed as a visible accessible table. The default omits PDF page chrome. CID image attachments accompany HTML and plain text. Responsive media rules survive; flex/grid, absolute positioning and print geometry do not. Gmail clipping produces a warning above 100 KB. Outlook 2019/365, Gmail web and iOS Mail acceptance remains pending Litmus/Email on Acid evidence; browser previews alone do not establish that compatibility.

Format generation remains 1. anchorId on nodes and link:{href,title?} on text, headings, images, barcodes and table columns are additive optional fields. Rich-text hrefs gain bindings and document targets. Older strict readers can reject the added keys. Body {{@pageNumber}}, {{@totalPages}} and {{pageRef "anchor"}} use expression syntax without new model fields. Legacy templates retain their existing single-print path and page-chrome behavior. The frozen links-and-anchors.json corpus fixture records this generation. See support and verification.

Wave 52: additive label, text-fit and barcode fields

Existing definitions without the new fields retain their renderer paths. Older servers reject repeater.layout, text.fit/heading.fit, barcode payload/colours/ rotation/quietZone and new barcode enum values under strict validation. Upgrade all render workers and API servers before saving such templates.

Feature PDF HTML DOCX PPTX CSV/XLSX
Label sheets Exact page grids CSS sheet grids Fixed tables, exact rows Flow fallback + warning Table extraction unchanged
Text shrink Loaded-font measurement Estimate for absolute widths Font-agnostic estimate Estimate; positioned native shrink N/A
Clip / ellipsis CSS CSS Estimated truncation Estimated truncation N/A
New barcodes / builders SVG SVG SVG + PNG fallback PNG N/A

Office layout and printer registration still need inspection on the user’s Word/PowerPoint and printer. Swiss QR payload/symbol support does not provide the full regulated payment-part layout or carrier certification for postal symbols.

Grids and form controls (Wave 53)

Format generation remains 1. grid (with id-bearing gridRow/gridCell structures), shape, checkbox, comb, and table-column repeatedValues are additive. Older strict readers can reject these fields. Existing templates with absent or show duplicate handling retain their rendering. The frozen grid-forms-wave53.json fixture records the new generation.

Feature HTML / PDF DOCX PPTX XLSX / CSV
Static grid Native table, spans, repeated header rows Native fixed-width table, gridSpan/vMerge, repeated headers, scoped nested tables Native editable table and spans; text flattened from text/headings/rich text/containers/conditionals/references Layout omitted; nested data tables still discovered
Grid checkbox child Vector checkbox Toggleable content control Checkbox symbol and label as plain text Omitted
Other grid child types Normal renderer Normal renderer Skipped with one unsupported_marker warning per unsupported child Data tables discovered
Repeated merge Hierarchical row spans Native vertical merge Suppress with table_cell_degraded warning XLSX native vertical merge; CSV writes every value
Repeated suppress Blank continuation cells Blank continuation cells Blank continuation cells Every value retained for filtering and sorting
Shapes Accessible SVG Horizontal line is a paragraph border; other shapes rasterised Editable native rect/roundRect/ellipse/line/arrow, rotation/dash/flip/arrows Omitted
Checkbox Accessible SVG, condition or JEXL state Native toggleable box/tick/cross; radio rasterised Raster checkbox plus native label Omitted
Character comb Fixed-size vector borders and text Native N-cell table Native N-cell table Omitted

Grid row and cell visibility retain the physical slots while clearing hidden content. Basic physical borders, padding and background colours carry to Office output; arbitrary CSS layout and rich formatting do not. PowerPoint uses uniform cell borders/padding; Word also maps per-edge borders. PowerPoint grid text is flattened, and grid double/dotted borders approximate the nearest supported line style. PowerPoint grids use slide flow and overflow warnings rather than printed-page header repetition. Grid children that cannot fit a slide remain subject to existing overflow behavior.

Runs compare primitive values, Date timestamps and JSON object strings; null/undefined compare equal and empty strings remain distinct. Merging in an Excel data column affects sorting/filtering, so use Show or Hide duplicates for operational spreadsheets. Page-aware table totals/continuation bands cannot combine with merge; validation requires suppress or show. A printed row span may split across pages; its content stays on the first fragment.

See Wave 53 verification.

Output fidelity is independent of formatVersion: see the generated format support matrix. renderConfig.targetFormats is additive in format 1.

Raw HTML conversion bypasses the template model. Production inline definitions use the same additive format-version validation as saved definitions.

Hyphenation and flow columns (Wave 63)

Optional hyphenation and typed flow styles keep formatVersion 1. Templates without these settings retain byte-identical HTML. HTML/PDF use eleven bundled, audited pattern packs and manual discretionary hyphens; no host dictionaries or network are required. Unknown languages skip insertion with one warning. PDF extraction may preserve U+00AD and split words at line ends.

DOCX uses native Word hyphenation without soft hyphens and continuous sections for columned containers/sections. Direct-child full-width spans work; page setup, numbering boundaries and inherited chrome are preserved. Word always balances, reduces dividers to a plain rule and renders nested/table-cell flow regions in one column. Per-node hyphenation overrides and minimum-word-length settings are HTML/PDF-only. PPTX ignores hyphenation and renders flow in one column with PPTX_UNSUPPORTED_STYLE. CSV/XLSX ignore these layout controls and receive no inserted soft hyphens.

The Wave 63 report records the print checks and unmet HTML-build overhead target.

PDF forms (Wave 65, unreleased)

Format generation remains 1. formField, signatureField.emitPdfField, root pdfForm, and request options.pdf.forms are additive. Older strict readers reject these additions; existing templates require no migration. The form post-pass is skipped when a template has no form fields.

Feature HTML / PDF DOCX PPTX CSV / XLSX
formField HTML boxes/defaults; interactive PDF AcroForm or flattened/static boxes Native checkbox; static bordered defaults for other types Static field placeholder and warning Ignored
signatureField.emitPdfField Standard empty PDF signature widget plus existing anchor Existing anchor Existing stub Ignored
Root pdfForm PDF only; original asset with evaluated bindings Rejected with 422 Rejected with 422 Rejected with 422

See PDF form usage for choice export values, XFA, font coverage and calculation limitations. Form-backed templates require the original tenant-owned PDF asset; include it when migrating templates between environments.

Editable PDF fields embed the complete body TTF/OTF font. WOFF/WOFF2 body fonts use the bundled OFL form font for field appearances because web-font containers cannot be embedded directly as PDF font streams.

Wave 66 adds optional renderConfig.pdf.optimize, sizeBudgetKb, sign, and signatureField.seal without changing formatVersion 1. Existing templates render as before. Preview never applies a digital signature. Persist only certificate IDs and public reason/location expressions; deployment secret fields are rejected by strict schemas. Readers and older editor servers may lack these capabilities; inspect /capabilities before authoring them.

Wave 67 adds renderConfig.pdf.attachments and format-agnostic renderConfig.eInvoice, retaining formatVersion 1. Templates store adapted paths/table references, not attachment bytes. The Electronic Invoice starter pack uses the canonical EN 16931 model. Saved settings are ignored outside PDF (except XML-only /render/einvoice), and PDF previews omit embedded data. Attachments conflict with PDF/A-2b; hybrid e-invoices require PDF/A-3b and prohibit encryption. Existing templates without these settings retain their previous output. JSON/ZIP batch output preserves individual invoices; page-only merged/book/source output rejects embedded data.

Feature Support Behavior
SQL data sources PostgreSQL / MySQL / SQL Server Resolved before PDF, HTML, DOCX, PPTX, XLSX and CSV dispatch; server flag and least-privilege read-only connection required.

CSV, XML and XLSX input formats map to JSON independently of output format. Sources default to JSON; parsers are server-only and lazy-loaded.

E-signature fields

formatVersion: 1 is unchanged. The optional root esign signer declaration and signature-node required property are additive; a frozen pre-change fixture is exercised by the renderer tests. PDF supports anchored signing workflows; HTML carries hidden anchors and dry runs collect the actual rendered fields. DOCX now interpolates signature anchors and shows the display label only when hidden === false (previous default behavior was inconsistent with HTML). PPTX placeholders remain visual only; XLSX and CSV do not provide signing anchors.

Guided-form images and signatures

Image/file and signature widgets submit PNG/JPEG data URIs in strings. Bind them with image src, such as {{photo}}. HTML/PDF display them, DOCX embeds them, and PPTX uses existing image support when enabled. CSV/XLSX export tabular data and ignore image/signature nodes. Uploads re-encode PNG/JPEG/WebP, reject SVG, and default to 1600 px and 262144 bytes per field. Form submissions are capped at 900 KiB.

Positioned anchors and rotation

anchor and rotation are optional additions to format 1. An omitted anchor retains container placement. page and everyPage must be direct section children; nested anchors are rejected by validation. Rotation is clockwise about the box centre and must be finite, from -360 to 360 degrees. Layer order uses style.zIndex.

Feature HTML / PDF DOCX PPTX CSV / XLSX / email
Container anchor Existing containing-block behavior Inline children, warning Slide-edge coordinates, existing behavior Children in flow
Page anchor Paper-edge coordinates on section’s first page Page-relative paragraph frames and floating images Slide-edge coordinates on the current slide Children in flow
Every page Fixed box on all printed pages; one screen instance Page-relative frames/images in each section header Replayed on every slide, including earlier slides Children in flow
Rotation CSS transform about centre Inline fallback with warning Text and image shape rotation Ignored
Z-index CSS stacking rules Floating image order; negative values behind document; text frames have no arbitrary z-index Stable order among positioned boxes, after flow content Ignored

DOCX frames support physical-unit text and headings; images float relative to the page. Tables and other positioned children fall back inline with a warning. Relative units and nonzero rotation fall back inline for the whole box. Word’s frame and floating-object layout remains viewer dependent; XML checks establish the exported structure, not a substitute for Word visual acceptance.

Chromium clips both fixed and absolute boxes outside the printable content area. Use a zero-margin page for full bleed, then add padding to flow containers. Page anchors require a section page break when they follow another section. The editor flags clipping, same-scope overlaps and missing section breaks. Positioned boxes do not establish a new arbitrary target page number.

Explicit differing PowerPoint z-index values now order positioned shapes; previous releases ignored those values. Equal or absent z-index values retain insertion order. Existing HTML and DOCX behavior is preserved when the new anchor/rotation fields are absent.

Fixed every-page boxes use the document’s root print margins. Mixed or mirrored page margins can shift their paper-edge position on later pages; use consistent margins for stationery that must repeat at identical coordinates. Page anchors use their own section’s margins. Container boxes keep the existing renderer semantics and a local canvas editing stage; use paper anchors for paper-accurate canvas placement.

Template kinds

Missing kind remains a visual document. Existing document, theme, component and layout kinds retain their contracts. Office templates use kind office and an immutable private source reference instead of a document AST. Their native format matches the source; PDF uses the optional converter; HTML, CSV and mismatched native outputs return 422. See Office templates for the format matrix and limits.

Imported legacy reports

Legacy converters emit ordinary formatVersion: 1 templates using existing nodes. Node/document meta.import records advisory provenance and review notes; it does not change rendering semantics. Output format support follows the emitted nodes. Absolute imports are approximated for DOCX/PPTX; review all fidelity items before using a draft. See migration guidance.