Blank values and defaults
Every template ships with values already in it — the text the author typed while designing, the logo they placed, the sample rows in a table. Those values are what makes a template previewable before anyone has sent it any data.
When you generate a document, each field resolves through one rule:
| What you send | What the document shows |
|---|---|
| A value | that value |
An empty value ("") | nothing — the field prints blank |
| Nothing at all (the key is absent) | depends on the engine, below |
Empty and absent are not always the same thing. Sending "" always prints nothing. Leaving the key out asks the engine for whatever it considers the field's default, and the three engines answer differently — because what counts as a default differs in kind.
- Typst has no defaults. An absent key prints blank, exactly like
"". The values in the template's#let datablock are sample text for previewing, not fallbacks. - Canvas falls back to the layer's own design. Those values are the artwork, not sample data.
- DOCX falls back to the default saved against that field in Manage template, if one is set.
The rule behind all three: a default is something someone deliberately configured. Canvas layers and saved DOCX defaults qualify. Text typed into a Typst template to make it preview does not.
Want a fallback in a Typst template? Write one. Typst is a programming language, so #if data.company == "" { … } can substitute a value, drop the heading above it, or collapse the space entirely — none of which a saved default could do.
API
POST /v1/renders — you control the data object completely, so all three columns are reachable.
| Engine | Key sent with a value | Key sent as "" | Key not in data |
|---|---|---|---|
| Typst | that value | blank — text prints nothing, an image leaves empty space where the template put it | blank, the same as "" |
| Canvas | that value | blank — text and images alike | the layer's own value |
| DOCX | that value | blank | the field's saved default from Manage template, or blank if it has none |
A request carrying no data at all renders the template exactly as designed on every engine. On canvas and DOCX that falls out of the ordinary rule — every key is absent, so every field takes its default. On Typst it is a deliberate exception, since the ordinary rule would blank the whole page: send nothing and you get the template, send one field and every other field blanks.
Two engine notes worth knowing:
- Canvas styling properties do not clear.
fontSize,filland the other appearance properties keep the template's value when sent as"", because a font size of nothing is not a font size. Only content — a text layer'stext, an image'ssrc— is cleared by an empty value. - DOCX defaults live on the field, not in the file. There is nothing inside the
.docxto fall back to. What fills an absent key is the default saved against that field in Manage template, so a DOCX field with no saved default renders blank whether you send""or nothing.
Forms
A form always sends every field it is mapped to, including the ones the respondent left empty. There is no "absent" case for a mapped field.
| Engine | Respondent fills it in | Respondent leaves it empty |
|---|---|---|
| Typst | that value | blank |
| Canvas | that value | blank |
| DOCX | that value | blank |
This is deliberate. A respondent who skips an optional question has told you that question has no answer, and printing the template's sample text in its place would put words in their mouth.
To use the template's own value instead, set that variable to Use template default in the form's Document tab, or leave it unmapped. That is a decision the form author makes once, for every response — not something an individual respondent can trigger by leaving a box empty.
Most fields on a generated form are marked required, so "left empty" usually only happens where the author turned Required off. Canvas image fields are the exception: they are optional by default.
Generate page
The Generate page sends every field on the form, so it never leaves a key out. What an untouched field sends depends on how the box was pre-filled, and that differs by engine.
| Engine | You type a value | You clear the box | You never touch it |
|---|---|---|---|
| Typst | that value | blank | blank |
| Canvas | that value | blank | the template's own text — the box is pre-filled with it, so it is sent as a value |
| DOCX | that value | blank | blank, unless the field has a saved default in Manage template |
Canvas boxes arrive pre-filled with the template's own text, so you are editing a design you can already see rather than retyping it. Generating without touching a box reproduces that text. Clear a box to print nothing there.
Image fields behave the same way on every engine. The control shows the template's current picture as a thumbnail, so leaving it alone keeps that picture — the field is not sent at all. Upload a file or paste a URL to replace it, or clear the field to print nothing there.
Bulk generate from CSV
Each row becomes one document, and only the columns you mapped are sent. A template field with no column mapped to it is absent from every row.
| Engine | Cell has a value | Cell is empty | No column mapped to the field |
|---|---|---|---|
| Typst | that value | blank | blank |
| Canvas | that value | blank | the layer's own value |
| DOCX | that value | blank | the field's saved default, or blank |
On canvas, a partial mapping is useful: map the three columns that change per row and every document keeps the rest of the design. On Typst it is the opposite — an unmapped field is blank on every row, so the mapping needs to cover every field that should carry a value. Anything constant across a run belongs in the template body rather than in #let data.
Other ways to generate
The same rule applies everywhere; only the way keys arrive changes.
| Surface | Where the keys come from | Can a key be absent? |
|---|---|---|
| Dynamic URLs | query parameters, or the encoded payload | Yes — ?title= sends an empty value, omitting title sends nothing |
| Airtable and Google Sheets automations | the mapped columns of the source row | Yes — an unmapped field is absent, an empty cell is an empty value |
MCP and /v1/collections | the caller's data object | Yes — same as the API |
Preview is not a render
The preview in the template editor fills every field with the template's own sample values, so it always shows the fully-populated document. It is not a guide to what a real render will print — a preview cannot tell you a field is going to arrive empty. Generate a document, or send one API call, to see that.
Last updated on