Skip to main content

Your first template

A template is a directory. The directory name is the template name used in the URL (/templates/<name>/render). Only the body template is required; everything else is optional.

invoice/
template.handlebars # body — REQUIRED
header.handlebars # optional page header
footer.handlebars # optional page footer
schema.json # optional JSON Schema for request data
params.json # optional PDF print options
examples/
sample.json # optional example datasets
assets/
styles.css # optional static files, referenced as ./assets/...
logo.svg
partials/
line-item.handlebars # optional reusable fragments

The body template

The body file's extension selects the engine: template.mustache, template.handlebars, template.tmpl (Go), or template.html (static). If several exist, the first in that priority order wins.

<!-- template.handlebars -->
<!doctype html>
<html>
<head><link rel="stylesheet" href="assets/styles.css"></head>
<body>
<h1>Invoice {{number}}</h1>
<p>Billed to: {{customer.name}}</p>
</body>
</html>

The request JSON body becomes the template data: {"number": "A-1", "customer": {"name": "Alice"}}.

Schema (schema.json)

An optional JSON Schema. Request data is validated before rendering; invalid data returns 422 and never reaches the browser. The schema is also published at GET /templates/<name>/schema.json.

PDF options (params.json)

Optional PDF print parameters: page size, margins, orientation, background printing, scale, and which lifecycle event to wait for.

{ "pdf": { "landscape": false, "printBackground": true, "marginTop": 0.5 } }

Optional header.<ext> and footer.<ext> files render the running page header and footer. They use the same engines as the body but do not have access to assets. See Headers & footers.

Examples (examples/*.json)

Each JSON file is a named example dataset. It powers GET /templates/<name>/examples/<example> (renders a PDF), GET /templates/<name>/examples-data (returns the data), the tester UI, and the validate CI check. Commit at least one — it is your fixture and your docs.

Assets and partials

assets/ holds static files referenced from the body as ./assets/<path> (served to the browser at render time). partials/ holds reusable fragments for Handlebars, Go, and Mustache templates. See Assets and Partials.

Next