What is a template?
A template is a reusable document design made of four parts:| Part | Required | Purpose |
|---|---|---|
htmlTemplate | Yes | The document structure and layout (HTML + Liquid tags) |
mockData | Yes (in Studio) | Sample data used for live preview |
customCss | No | Extra CSS appended to the document |
settings | Yes (has defaults) | Paper size, orientation, margins, header, footer |
data you send is merged into htmlTemplate to produce the final HTML, which is then converted to a PDF.
The Studio
Open pdfgorilla.io/playground to experiment quickly, or the Studio (/templates/:id) to work on a saved template.
Both have:
- HTML, JSON (mock data), CSS, and Settings tabs with live syntax validation
- A Generate button (or
Cmd/Ctrl + S) that renders a preview PDF in the right panel - A Copilot panel for AI-assisted editing
- A Beautify button to auto-format code
- A Fullscreen editor mode (
Escto exit) - Download PDF to save the preview
- Version history: browse, preview, and restore the last 50 saved versions
- Import / Export: backup and restore template JSON
Liquid templating
PDF Gorilla uses LiquidJS in non-strict mode, which means:- Missing variables render as empty strings (they don’t crash)
- Unknown filters are silently ignored
Variables
data object exactly, including case.
Loops
forloop.index counts from 1. Use forloop.first and forloop.last for conditional styling.
Conditionals
Useful filters
CSS and print styling
Use a<style> block inside htmlTemplate, or write CSS in the CSS tab (sent as customCss).
Print-specific tips
printBackground: true, so background colors and images will appear in the PDF.
External assets (images, fonts)
External URLs (e.g.<img src="https://...">) are fetched by the browser during render. They must be publicly reachable. Slow or unavailable resources can cause render timeouts.
Use the Assets library (see below) to host images and reference them in templates. Files are stored privately; the app serves them only to signed-in users.
Assets library
Upload reusable images (logos, signatures, icons) at /assets.- Supported formats: PNG, JPG, WEBP
- Max file size: 2 MB per image
- Max images per account: plan-dependent (default Free: 10, Pro: 100)
- A stable
asset:TAGURI you can use in<img src="...">and CSSurl()values — e.g.asset:logo - An
@tag(e.g.@logo) you can mention in Copilot prompts - Use the Copy tag button on the Assets page to copy the
asset:TAGvalue
asset:TAG references to short-lived signed links so the render service can fetch the image. The older /api/assets/{id} format still works but asset:TAG is preferred for readability. Other external URLs in your template must still be publicly reachable by the render service.
Page settings
Configure via the Settings tab in the Studio, or insettingsJson on the template record.
| Setting | Default | Options |
|---|---|---|
format | a4 | a0 to a6, letter, legal, tabloid, ledger |
orientation | portrait | portrait, landscape |
marginTop | 14mm | Any CSS length (mm, in, px, cm) |
marginRight | 12mm | |
marginBottom | 14mm | |
marginLeft | 12mm | |
headerLeft/Center/Right | "" | Plain text + tokens (see below) |
footerLeft/Center/Right | "" / [page]/[topage] | Plain text + tokens |
Header and footer tokens
Headers and footers are plain text, not Liquid: they are not rendered through the template engine. Use these special tokens:| Token | Replaced with |
|---|---|
[page] | Current page number |
[topage] | Total page count |
[date] | Current date |
[title] | Page <title> |
[url] | Page URL |
Page [page] of [topage] → Page 3 of 12
Headers and footers are only rendered when at least one field is non-empty.
Copilot (AI assistant)
Click the Copilot icon in the top editor toolbar to open the AI chat panel. Copilot can generate or edit:- HTML template
- Mock data
- Custom CSS
- Settings (format, margins, header/footer)
- Describe what you want in plain language: “Add a two-column layout with the customer address on the left and invoice details on the right”
- Reference uploaded assets with
@tag: “Use @logo in the top-left corner” — Copilot emitsasset:TAGreferences that the server resolves automatically - Ask for iterations: “Make the table striped with alternating row colors”
- Send with
Enter; useShift+Enterfor a newline
Data format rules
Thedata (and mockData) must be a JSON object at the root, not an array, string, or number.
Validation behavior
The Studio validates your code on every edit (debounced) and shows a colored dot on each tab:- 🟢 Green: valid
- 🔴 Red: errors found (with line/column info when available)
- HTML: Liquid syntax + HTML tag balance
- JSON: Must be a valid JSON object at root
- CSS: Stylesheet parse
Common pitfalls
| Symptom | Likely cause | Fix |
|---|---|---|
| Variable shows as blank | Wrong key name in data | Check spelling and nesting: invoice.number not invoiceNumber |
Mock data must be a valid JSON object | Root is an array [] | Wrap in {} |
| Header/footer tokens not replaced | Typo in token | Use exactly [page], [topage], etc. |
| Preview times out | Slow external resource (font, image) | Remove or host assets locally / in Assets library |
| Page breaks in wrong place | Missing page-break-after: always | Add .page-break { page-break-after: always } between sections |