PDF4.dev
Learn

PDF format

Control the page size, margins, and global styles of your PDFs with the format object.

Presets

6 built-in presets are available:

PresetDimensionsUse case
a4210 x 297mmDefault. Standard in most countries.
a4-landscape297 x 210mmWide reports, dashboards
letter216 x 279mmStandard in the US
letter-landscape279 x 216mmUS landscape documents
square210 x 210mmSocial media, certificates
customUser-definedAny size with width and height

Default: a4 portrait with 20mm top/bottom and 15mm left/right margins.

Margins

All margins accept CSS length values (e.g., 20mm, 1in, 72pt):

{
  "format": {
    "preset": "a4",
    "margins": {
      "top": "20mm",
      "bottom": "20mm",
      "left": "15mm",
      "right": "15mm"
    }
  }
}

Custom dimensions

Set preset to custom and provide width and height:

{
  "format": {
    "preset": "custom",
    "width": "100mm",
    "height": "150mm",
    "margins": {
      "top": "5mm",
      "bottom": "5mm",
      "left": "5mm",
      "right": "5mm"
    }
  }
}

Global styles

Optional fields that inject a <style> tag into the <head> before rendering:

FieldDescriptionExample
background_colorPage background color"#ffffff"
font_familyDefault font family"Inter, sans-serif"
font_sizeDefault font size"14px"
colorText color"#333333"
line_heightLine height"1.5" or "24px"
google_fonts_urlGoogle Fonts URL (or any @import-compatible CSS URL). Loaded in <head>, available to the template and all attached components."https://fonts.googleapis.com/css2?family=Roboto&display=swap"
component_gapGap between header/footer components and page content"5mm"
footer_positionFooter position mode: "after-content" (default) places footer inline after content, "page-bottom" pins footer to the bottom of every page"after-content"
text_alignText alignment on body ("left", "center", "right", "justify")"left"
horizontal_alignHorizontal content alignment via flexbox align-items on body ("left", "center", "right")"center"
vertical_alignVertical content alignment via flexbox justify-content on body ("top", "center", "bottom"). Requires html { height: 100% } in your template."center"
Full format example
{
  "format": {
    "preset": "a4",
    "margins": {
      "top": "25mm",
      "bottom": "25mm",
      "left": "20mm",
      "right": "20mm"
    },
    "background_color": "#ffffff",
    "font_family": "Roboto, sans-serif",
    "font_size": "14px",
    "color": "#333333",
    "line_height": "1.5",
    "google_fonts_url": "https://fonts.googleapis.com/css2?family=Roboto&display=swap",
    "component_gap": "5mm",
    "footer_position": "after-content",
    "text_align": "left",
    "horizontal_align": "center",
    "vertical_align": "top"
  }
}

These styles apply as CSS defaults on the <body>. Your template's inline styles and <style> tags take precedence.

Overriding at render time

Templates have a stored pdf_format. You can override it per render request by passing format in the request body:

Override margins for a specific render
{
  "template_id": "invoice",
  "data": { "company": "Acme" },
  "format": {
    "preset": "letter",
    "margins": {
      "top": "10mm",
      "bottom": "10mm",
      "left": "10mm",
      "right": "10mm"
    }
  }
}

The format in the request completely replaces the template's stored format (no merging).

Component rendering

Header and footer components are rendered using <thead> and <tfoot> elements inside a full-page table. Chromium's print engine automatically repeats <thead> at the top and <tfoot> at the bottom of every printed page, making this approach reliable for multi-page documents.

The component_gap field controls the spacing between the header/footer and the page content. It is applied as padding on the <thead> and <tfoot> cells:

{
  "format": {
    "preset": "a4",
    "margins": { "top": "20mm", "bottom": "20mm", "left": "15mm", "right": "15mm" },
    "component_gap": "8mm"
  }
}

Components inherit all global styles from the format (font family, font size, color, line height, etc.) since they are injected into the same document body.

The footer_position field controls where the footer renders on the page:

ValueBehavior
"after-content" (default)Footer sits right after the last content row. On multi-page documents, it repeats at the bottom of intermediate pages but follows content on the last page.
"page-bottom"Footer is pinned to the bottom of every page, including the last page. Uses CSS position:fixed so it always appears at the page bottom regardless of content length.
{
  "format": {
    "preset": "a4",
    "margins": { "top": "20mm", "bottom": "20mm", "left": "15mm", "right": "15mm" },
    "component_gap": "5mm",
    "footer_position": "page-bottom"
  }
}