Skip to main content
The image node embeds a raster image, supplied as base64-encoded bytes inside the request.
Tipar passes the decoded bytes to the renderer, which detects the format — common raster formats such as PNG and JPEG work. URL-sourced images are not supported in v1; the bytes must travel in the request.
Do not include the data:image/png;base64, prefix that browsers and some libraries prepend. Send only the base64 payload itself. A value the renderer can’t decode (bad base64, or an unsupported format) returns 422 template.invalid_content.

Producing the base64

Encode the file’s bytes — strip any data-URL prefix first.

Controlling size with fit

fit decides how the image scales into the space its parent gives it. The space comes from the layout — most often a row cell with a constant width, or the page width inside a column.
Size an image by its width, not its height. There is no fitHeight. Content flows down the page, so the space a node is offered is bounded across but open-ended down — “make it exactly this tall” has nothing to resolve against. Put the image in a constant-width row item or table cell and use fitWidth; the height then follows the aspect ratio. To keep a lane of logos visually even, crop or pad them to a common aspect ratio before encoding.
A logo in a header lane is typically a fixed-width cell with fitWidth:
base64 is a text-like string, so it can be interpolated — "base64": "{{logo}}" pulls the encoded image from data. That keeps a large, static logo out of the template file and lets you swap it per tenant.
Images count toward the 4 MB request body cap. Optimise and resize before encoding — a 200 KB logo is plenty at print resolution, and base64 adds ~33% on top. Don’t ship a 5 MB photo where a downscaled one will do.

Next: Headers & footers

Repeat content on every page and add page numbers.