render
Renders a Liquid template with structured data. Templates use soft variables: a reference to a field that is absent from the data renders as empty text and its field name is included in warnings.
render is a filter: place the template source to its left and pass the data and optional locale as arguments.
Signature
import 'liquid'
text |> render (
data: value,
locale: text | nothing
) => {
output: text | nothing
warnings: [text]
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| template | text | Yes | The Liquid template source (left of render) |
data | value | Yes | Data available to the template — typically a record, map, or tuple |
locale | text | nothing | No | BCP-47 formatting locale; absent or unresolvable uses invariant formatting |
Pass the data argument explicitly
Pass data positionally — '…' render (model, 'sv-SE') — or name it — '…' render (data = model). Do not pass an unnamed record as the only argument: render ({ name = 'World' }) does not supply that record as data.
Returns
A record with two fields:
| Field | Type | Description |
|---|---|---|
output | text | nothing | The rendered text; nothing when rendering cannot complete |
warnings | [text] | Missing field names and any rendering messages; field values are never included |
When rendering cannot complete, output is nothing; it never returns partial output.
Locale-aware filters
The locale-aware filters — number, date, instant, duration, and percent — are available in every template. Their defaults come from the selected locale, and number, date, and instant each take an optional positional argument:
| Filter | Default | Optional argument | Example |
|---|---|---|---|
number | The value's own scale (1 299,5) | Decimals | {{ total | number: 2 }} |
date | The locale's short-date pattern | Date format string | {{ at | date: 'd MMMM yyyy' }} |
instant | The locale's general date-and-time pattern | Date and time format string | {{ at | instant: 'R' }} |
percent | The culture's percentage pattern | — | {{ fraction | percent }} |
duration | The duration's literal form | — | {{ span | duration }} |
Without a locale, filters use invariant formatting for predictable, culture-neutral output.
For currency amounts, format the amount before passing it to the template with the text module's formatMoney, then render the resulting text.
HTML safety
When rendering HTML, encode interpolated values (the standard escape filter is available) and sanitize the rendered output as appropriate for where it will be used.
Examples
Render with a bound model
import 'liquid'
from 'Hello {{ name }}!' render ({ name = 'World' }, nothing)
// Returns:
// { output = 'Hello World!', warnings = [] }A missing reference renders empty and warns
import 'liquid'
from 'Hello {{ name }}!' render ({}, nothing)
// Returns:
// { output = 'Hello !', warnings = ['name'] }Locale-aware number formatting
import 'liquid'
from 'Total: {{ total | number }}' render ({ total = 1299.5 }, 'sv-SE')
// Returns:
// { output = 'Total: 1 299,5', warnings = [] }The group separator is the locale's (a non-breaking space in sv-SE, which can look like a plain space).
Filter defaults follow the locale, arguments override
import 'liquid'
from 'Sent {{ at | date }}' render ({ at = 2026-10-10 }, 'sv-SE')
// Returns:
// { output = 'Sent 2026-10-10', warnings = [] }import 'liquid'
from 'Sent {{ at | date: ''d MMMM yyyy'' }}' render ({ at = 2026-10-10 }, 'sv-SE')
// Returns:
// { output = 'Sent 10 oktober 2026', warnings = [] }import 'liquid'
from 'Total: {{ total | number: 2 }}' render ({ total = 1299.5 }, 'sv-SE')
// Returns:
// { output = 'Total: 1 299,50', warnings = [] }Nested records and loops
import 'iterators'
import 'liquid'
from '{% for line in lines %}{{ line.name }} x{{ line.quantity }} {% endfor %}Total: {{ order.total | number }}' render ({
order = { total = 1299 },
lines = [{ name = 'Wool Beanie', quantity = 2 }, { name = 'Mittens', quantity = 1 }]
}, 'sv-SE')
// Returns:
// { output = 'Wool Beanie x2 Mittens x1 Total: 1 299', warnings = [] }A malformed template hard-fails
import 'liquid'
from 'Hello {% if %}' render ({}, nothing)
// Returns:
// { output = nothing, warnings = ['…'] }