Skip to content

Create a Template

Make your own invoice look in minutes. Start with a single HTML file, install via manifest, and preview it on real invoices.

Heads up: Installed templates are sanitized and limited for safety (no images, scripts, iframes, external CSS). See Reference → Template Syntax for variables and rules.

  1. Author your HTML

    Create a single self-contained HTML file. Keep CSS inline inside a <style> block. Avoid images and external assets.

    Minimal starter:

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8" />
    <title>Invoice</title>
    <style>
    body { font-family: system-ui, sans-serif; padding: 24px; color: #111; }
    h1 { margin: 0 0 16px; color: {{highlightColor}}; }
    .muted { color: #666; }
    table { width: 100%; border-collapse: collapse; margin-top: 16px; }
    th, td { border-top: 1px solid #ddd; padding: 8px 0; text-align: left; }
    </style>
    </head>
    <body>
    <h1>Invoice {{invoiceNumber}}</h1>
    <div class="muted">{{companyName}} → {{customerName}}</div>
    <div class="muted">Issued {{issueDate}}{{#dueDate}} · Due {{dueDate}}{{/dueDate}}</div>
    <table>
    <thead><tr><th>Description</th><th>Qty</th><th>Unit</th><th>Total</th></tr></thead>
    <tbody>
    {{#items}}
    <tr>
    <td>{{description}}</td>
    <td>{{quantity}}</td>
    <td>{{unitPrice}}</td>
    <td>{{lineTotal}}</td>
    </tr>
    {{/items}}
    </tbody>
    </table>
    <p><b>Total:</b> {{total}} {{currency}}</p>
    </body>
    </html>
  2. Host it and create a manifest

    Put your HTML file somewhere reachable over HTTPS (e.g., a GitHub raw URL or a static host). Then prepare a manifest (YAML or JSON):

    manifest.yaml
    schema: 1
    id: my-template
    name: Fancy Blue
    version: 1.0.0
    invio: ">=0.1.0"
    html:
    path: index.html
    url: https://example.com/templates/fancy/index.html
    sha256: "<hex-digest>" # optional integrity check
  3. Install from the frontend

    • Go to Settings → Templates.
    • Paste the manifest URL and click Install.
    • The template will appear in the list if it passes validation and sanitization.
  4. Set as default

    • In Settings → Templates, click “Set as default” on your template.
    • This updates the templateId used for HTML and PDF rendering.
  5. Preview and iterate

    • Open any invoice → View HTML / Download PDF to check layout.
    • Keep CSS simple and inline; wkhtmltopdf is conservative.
    • If HTML and PDF differ, simplify styles (no advanced layout) and retest.
  6. Manage templates

    • You can delete your custom templates from Settings (unless they’re the active default).
    • Built-ins (professional-modern, minimalist-clean) cannot be deleted.
  • Storage: Templates live in the DB; manifest installs also save files under backend/data/templates/<id>/<version>/ for asset use.
  • Default: The selected template comes from Settings (templateId); aliases like professionalprofessional-modern are normalized.
  • Sanitization: Installer blocks risky tags (script, iframe, object, embed, img, video, audio, link), external CSS imports/URLs, and inline event handlers. Max HTML size: 128KB.
  • Assets: An internal asset route exists, and external fonts/assets aren’t fetched; rely on inline styles.
  • Keep it small and self-contained (inline CSS; no images).
  • Use {{highlightColor}} and {{highlightColorLight}} for accents.
  • Dates and money values are already formatted strings.

See also