Skip to content

Making Templates

VoodooLikesCoding edited this page Nov 9, 2025 · 4 revisions

You can install custom HTML templates from a manifest URL, or create one locally while developing.

Concepts

  • A Template is an HTML file rendered with a simple Mustache‑like engine.
  • Data comes from the invoice and from Business Settings.
  • Built‑in IDs: professional-modern, minimalist-clean.
  • Installed templates are stored in the DB (HTML) and optional assets under /app/data/templates/<id>/<version>/....

Install from a manifest

Use Settings → Templates → “Install from manifest”, or call the API:

curl -u $ADMIN_USER:$ADMIN_PASS \
  -H "Content-Type: application/json" \
  -X POST "$BACKEND_URL/api/v1/templates/install-from-manifest" \
  -d '{"url":"https://example.com/invio-template/manifest.yaml"}'

Manifest (YAML or JSON) minimal schema:

id: clean-lines
name: Clean Lines
version: "1.0.0"
invio: ">=0.1.0"
html:
  path: index.html
  url: https://example.com/clean-lines/index.html
# license: MIT
# source:
#   manifestUrl: https://example.com/clean-lines/manifest.yaml
#   homepage: https://example.com/clean-lines/

Security guardrails: Templates cannot include iframes/objects/embeds or inline on* handlers.

Update or delete

  • Update installed template if its manifest URL is stored: POST /api/v1/templates/:id/update
  • Delete installed template: DELETE /api/v1/templates/:id (built‑ins are protected)

Template context

Available variables your HTML can use (subset):

Company

  • companyName, companyAddress, companyEmail, companyPhone, companyTaxId
  • logoUrl (prefer this; system tries to inline remote logos as data URIs)

Invoice

  • invoiceNumber, issueDate, dueDate, currency, status

Customer

  • customerName, customerEmail, customerPhone, customerAddress, customerTaxId

Items

  • items (array of { description, quantity, unitPrice, lineTotal, notes })

Totals

  • subtotal, discountAmount?, discountPercentage?, taxRate?, taxAmount?, total
  • taxSummary? (array of { label, percent, taxable, amount }) and hasTaxSummary
  • netSubtotal (subtotal after discount, before tax)

Payment/Notes

  • paymentTerms?, paymentMethods?, bankAccount?, notes?

Extras

  • brandLogoLeft is always true in current renderer
  • highlightColor and highlightColorLight for custom branding

Internationalization

  • Template labels (like "INVOICE", "BILL TO", "TOTAL") are automatically translated based on the locale setting
  • The backend injects localized labels via the i18n system
  • No need to hardcode labels in your template — the system handles this
  • See Guides/Adding Translations for details on adding new languages

Blocks (conditionals/loops):

{{#items}}
  <tr>
    <td>{{description}}</td>
    <td class="num">{{quantity}}</td>
    <td class="num">{{unitPrice}}</td>
    <td class="num">{{lineTotal}}</td>
  </tr>
{{/items}}

Defaults: You can use {{var || 'Default'}} to fall back when a value is empty.

Clone this wiki locally