Template syntax

Templates are HTML/CSS documents with Handlebars placeholders. The fields you reference become the data you send to /v1/generate.

Placeholders & loops

<h1>Invoice {{invoice_number}}</h1>
<p>Bill to: {{customer.name}}</p>

<table>
  {{#each items}}
  <tr>
    <td>{{this.description}}</td>
    <td>{{currency this.amount ../currency}}</td>
  </tr>
  {{/each}}
</table>

{{#if notes}}<p class="note">{{notes}}</p>{{/if}}

Helpers

The following helpers are available for formatting (they never compute business logic):

  • {{currency total "USD"}}: format a number as currency
  • {{date issue_date "medium"}}: format a date (short, medium, long, full, or iso)
  • {{number qty 2}}: format a number with fixed decimals
  • comparisons (for {{#if (eq a b)}}): eq, ne, gt, gte, lt, lte, and, or

Full helper list: currency, number, date, eq, ne, gt, gte, lt, lte, and, or, code128.

Templates format, your code computes

Keep business math out of templates: pass computed values like subtotal, tax and total in your data. This keeps generation deterministic and avoids rounding bugs.

Every template is a typed API

On publish, Doclinth derives a Draft 2020-12 JSON Schema from the Handlebars structure and sample data. Fetch it from GET /v1/templates/:id/schema, or add ?format=typescript, zod, or pydantic. Set options.validate: true on generation to reject missing or mistyped data with field-level errors before rendering.

Save named payload fixtures for your own edge cases, then run the document-test suite to combine them with automatically generated layout stress cases.

Page size, fonts & images

  • Set the page size with CSS @page { size: A4 } (A6 and Letter are also supported). doclinth adds a sensible default if you omit it.
  • Use page-break-inside: avoid on table rows so long tables paginate cleanly.
  • Use system/standard font stacks or self-hosted @font-face. Reference a logo via a {{logo_url}} placeholder or a data: URI.

The fastest way to build one is the AI authoring editor: describe the document and refine the result live.