Template structure
When you open the Template tab in Studio, you’re editing a single JSON document that defines the whole template — its page setup, layout, styling, and where data is filled in. This page is the reference for that structure.
You rarely need to write this from scratch — the AI Assistant generates and edits it for you. This reference is for when you want to read the definition or change it precisely by hand.
The document at a glance
Section titled “The document at a glance”A template is a JSON object. The only property you always need is elements; everything else has a sensible default.
{ "pageSize": "a4", "pageMargins": { "top": 57, "bottom": 57, "left": 57, "right": 57 }, "elements": [ { "type": "text", "content": "Hello {{customerName}}" } ], "headers": [], "footers": [], "pageBackgrounds": [], "watermarks": []}Page setup
Section titled “Page setup”These are the top-level (root) properties.
| Property | Type | What it does |
|---|---|---|
pageSize |
a4 · letter · legal · custom |
Page size. Defaults to a4. |
pageOrientation |
portrait · landscape |
Page orientation. Defaults to portrait. |
customPageWidth / customPageHeight |
number (mm) | Page dimensions in millimetres. Required when pageSize is custom. |
pageMargins |
spacing | Margins on every page, in points. Defaults to 40 on each side. |
defaultFontFamily |
string | Default font for all text that doesn’t set its own. See Fonts. |
pageBackgrounds |
array | Per-page background colour/image — see Page backgrounds. |
headers / footers |
array | Content repeated at the top/bottom of pages — see Headers and footers. |
watermarks |
array | Overlays drawn on top of (or behind) page content — see Watermarks. |
elements |
array | The document body: elements rendered top-to-bottom in order. |
Most page setup is also editable through the visual Page Properties form — see Edit by hand → Page setup.
Layout: rows and columns
Section titled “Layout: rows and columns”elements are stacked top-to-bottom in the order they appear. To place things side by side, use a row with columns:
{ "type": "row", "gutter": 20, "columns": [ { "width": { "value": 0.25, "type": "proportional" }, "elements": [ /* … */ ] }, { "width": { "value": 0.75, "type": "proportional" }, "elements": [ /* … */ ] } ]}gutter— horizontal space (points) between columns. With N columns there are N−1 gutters.- Each column has an optional
widthand its ownelementslist (which flow top-to-bottom inside the column). - A column
widthhas avalueand atype:proportional—valueis a fraction of the row (0.25= 25%). This is the default.absolute—valueis a fixed width in points.
- Columns with no
widthshare the remaining space evenly. - A
rowcan also draw a verticaldividerbetween its columns.
Tables
Section titled “Tables”A table lays out a grid with fixed column widths, optional header rows, and body rows that can repeat over data.
{ "type": "table", "columnWidths": [ { "value": 0.5, "type": "proportional" }, { "value": 0.5, "type": "proportional" } ], "defaultBodyCellBorder": { "bottom": { "width": 0.5, "color": "#E0E0E0" } }, "headers": [ { "backgroundColor": "#17395D", "cells": [ { "elements": [ { "type": "text", "content": "Description", "typography": { "bold": true, "color": "#FFFFFF" } } ] }, { "elements": [ { "type": "text", "content": "Total", "alignment": "right", "typography": { "bold": true, "color": "#FFFFFF" } } ] } ] } ], "rows": [ { "dataSource": "lineItems", "cells": [ { "elements": [ { "type": "text", "content": "{{description}}" } ] }, { "elements": [ { "type": "text", "content": "{{total as currency('EUR')}}", "alignment": "right" } ] } ] } ]}Table properties
| Property | What it does |
|---|---|
columnWidths |
Array of { value, type } (see widths); the length defines the number of columns. |
headers |
Header rows, repeated at the top of the table on each page. |
rows |
Body rows. Each is static or data-bound (see below). |
border |
Outer border of the whole table. |
defaultHeaderCellBorder / defaultBodyCellBorder |
Default cell borders, overridable per cell. |
Row properties (headers and rows entries): cells, dataSource (repeat — see Repeating content), condition, backgroundColor, minHeight.
Cell properties (cells entries): elements, padding, backgroundColor, border (per-side, see Borders), verticalAlignment (top · middle · bottom), and colSpan / rowSpan for spanning.
Data and expressions
Section titled “Data and expressions”This is how data gets into the document.
Placeholders
Section titled “Placeholders”Wrap a property from your data model in double braces. Use dots for nested values:
{{invoiceNumber}}{{customer.name}}Placeholders work in text content, in colours and image sources, and in most string fields — the reference notes where.
Formatting values
Section titled “Formatting values”Append as <formatter>(…) inside the braces to format a value, for example:
{{issueDate as date(dd-MM-yyyy)}}{{unitPrice as currency('EUR')}}System values
Section titled “System values”{{_system.*}} placeholders (date, page context, user, organisation, …) are injected automatically at render time. The full list is in the editor’s System Data tab — see Edit by hand.
Conditions
Section titled “Conditions”Most elements (and table rows) accept a condition string that decides whether they render. Two forms:
- Truthiness —
{{Paid}}renders the element when the value is truthy (atrueboolean, a non-empty string, a non-empty collection, or any non-null object). - Comparison —
{{PropertyPath}} op value, whereopis=,!=,>,<,>=, or<=. The value is a number, a quoted string, or a boolean. Prefer single quotes for strings (the whole condition is already inside a double-quoted JSON string):
{ "type": "text", "content": "DRAFT", "condition": "{{status}} = 'draft'" }String and boolean comparisons support only = and !=.
Repeating content
Section titled “Repeating content”To render something once per item in a collection, bind a data source. The property name is the plain name, without {{ }}. Inside the repeat, placeholders resolve against the current item.
- Table rows — set
dataSourceon a row (see the table example). loop— setdataSourceProperty; itschildrenrender once per item.list— setdataSourceProperty+itemTemplate(e.g."{{name}}").checkbox— setdataSourceProperty/optionsDataSourceProperty.
Properties every element shares
Section titled “Properties every element shares”Every element has a type plus these optional properties (from the element base):
| Property | Type | What it does |
|---|---|---|
margin |
spacing | Outer spacing (points). Defaults to 0 on all sides. |
padding |
spacing | Inner spacing (points). Defaults to 0. |
backgroundColor |
colour | Fill behind the element. |
condition |
string | Render conditionally — see Conditions. |
position |
{ x, y } (cm) |
Absolute position from the page’s top-left corner. When set, the element is taken out of the normal flow. |
rotation |
number (deg) | Clockwise rotation around the element’s centre. |
verticalAlignment |
top · middle · bottom |
Vertical alignment within its parent (row column, cell, border box). |
A spacing value is { top, bottom, left, right } in points (any side optional). A colour is a hex string like "#17395D" or a two-stop linear gradient like "linear-gradient(90deg, #17395D, #E08A2B)".
Typography
Section titled “Typography”Text-bearing elements take a typography object:
| Property | Default | |
|---|---|---|
fontSize |
12 |
Points. |
fontFamily |
"Arial" |
See Fonts. |
bold / italic / underline |
false |
|
color |
"#000000" |
Hex or gradient. |
lineSpacing |
1.0 |
Multiplier of the font’s natural line height. |
Element reference
Section titled “Element reference”Every element sets type and inherits the shared properties above. The fields below are each element’s own.
Content elements
Section titled “Content elements”text — a run of text.
| Field | Notes |
|---|---|
content |
The text; may contain placeholders. |
typography |
See Typography. |
alignment |
left (default) · center · right · stretch. |
translationKey |
Resolve the text from the Translations dictionary instead of content. |
columns |
Optional multi-column layout: { count (≥2), gap, maxHeight, fillType: grow|divide, rule }. |
{ "type": "text", "content": "Invoice", "typography": { "fontSize": 18, "bold": true, "color": "#3E6491" } }html — rich text from an HTML string (content), with typography and alignment. Use it for inline styling that plain text can’t express; supports {{placeholders}} and a set of common HTML tags.
image — source, maxWidth, maxHeight (points), alignment. The source can be a gallery reference (pagr-image://<id>), a URL, a base64 data URI, or a {{placeholder}} that resolves to one. The image scales down to fit the max box while keeping its aspect ratio.
list — a bulleted or numbered list.
| Field | Notes |
|---|---|
listStyle |
disc (default) · dash · circle · decimal · lowerAlpha · upperAlpha · lowerRoman · upperRoman. |
items |
Static array of strings (each supports placeholders). |
dataSourceProperty + itemTemplate |
Data-bound items — see Repeating content. |
indentWidth |
Points reserved for the marker column. |
itemSpacing |
Vertical gap between items (points, default 2). |
checkbox — one or more checkbox options. Provide options (each { label, value }) or bind them with optionsDataSourceProperty; dataSourceProperty decides which are checked. Style with checkedStyle (check · cross · filledSquare · circle · filledCircle), boxColor, checkColor, and optionLayout (vertical · horizontal).
qrCode — content (the value to encode, supports placeholders), size (points, default 80), alignment, color.
pageNumber — a page counter. format uses {current} and {total} (e.g. "Page {current} of {total}"), plus typography and alignment.
Layout & structure elements
Section titled “Layout & structure elements”row — side-by-side columns, with gutter and optional divider. See Layout.
table — a grid with headers, rows, and cell borders. See Tables.
loop — repeat a block of children once per item in dataSourceProperty. keepStartTogether: true pushes the loop to a new page if the first item wouldn’t fit. See Repeating content.
border — a box drawn around child children.
| Field | Notes |
|---|---|
borderColor |
Hex; defaults to black. |
borderWidth |
Per-side widths (a single number for uniform, or { top, right, bottom, left }). |
cornerRadius |
Points; 0 for sharp corners. |
sizing |
stretch · shrink · fill. |
pageBreak |
close · continue — how the box behaves when its content spills onto a new page. |
separator — a horizontal rule: thickness (points, default 1) and color (hex or gradient).
pageBreak — starts a new page. Optionally changes pageSize / pageOrientation / customPageWidth / customPageHeight for that page and all pages after it — handy for a landscape page inside a portrait document.
Graphics elements
Section titled “Graphics elements”shape — a vector rectangle, ellipse, or line.
| Field | Notes |
|---|---|
shape |
rectangle (default) · ellipse · line. |
width / height |
Bounding box in points. |
fillColor |
Hex or gradient; omit for no fill. |
strokeColor / strokeWidth / strokeStyle |
Outline; strokeStyle is solid · dashed · dotted. |
cornerRadius |
For rectangles. |
lineStart / lineEnd |
{ x, y } in cm — only for line. |
graph — a chart rendered from a Chart.js configuration object.
| Field | Notes |
|---|---|
chart |
The Chart.js config (type, data, optional options); may contain {{placeholders}}. |
title |
Optional heading above the chart. |
width / height |
Points (height defaults to 250). |
chartBackgroundColor |
Canvas background (default transparent). |
theme |
{ brand, pixelRatio } — brand colour and raster sharpness. |
Page-level features
Section titled “Page-level features”Headers and footers
Section titled “Headers and footers”headers and footers each hold definitions with a displayOn rule and their own elements:
"footers": [ { "displayOn": "allPages", "elements": [ { "type": "pageNumber", "format": "Page {current} of {total}", "alignment": "center" } ] }]displayOn accepts allPages, firstOnly, lastOnly, allPagesExceptFirst, allPagesExceptLast, oddPages, or evenPages.
Watermarks
Section titled “Watermarks”Each watermarks entry overlays text or an image on the page:
| Field | Notes |
|---|---|
type |
text or image. |
content / source |
Text content, or image source (same formats as image). |
displayOn |
Same options as headers/footers. |
layer |
front or behind page content. |
opacity |
0.0–1.0 (default 0.3). |
rotation |
Degrees. |
anchor |
center (default) · topLeft · topRight · bottomLeft · bottomRight, or set explicit x / y in cm. |
Page backgrounds
Section titled “Page backgrounds”Each pageBackgrounds entry targets a page (1-based) or acts as the default when page is null. Set a color, an image, or both. A background image takes a source plus optional size, position, opacity, rotation, and margin.
"pageBackgrounds": [ { "page": null, "color": "#FFFFFF" } ]Related articles
Section titled “Related articles”- Variables and the data model — how the data these placeholders reference is defined.
- Edit by hand — the tabs, Studio vs Canvas, and the Page Properties form.
- Build with AI — generate and change this definition by describing what you want.
- Image Gallery and Fonts — the assets you reference from
sourceandfontFamily.
