Skip to content

Headers, footers and page numbers in HTML-to-PDF

, 5 min read

Running headers, “Page 3 of 12” footers and repeated table headers are the details that make a generated report look finished. Chromium supports all of them, with a few quirks worth knowing.

Header and footer templates

Pass headerHtml and footerHtml. Chromium renders them in a separate context on every page and fills in these classes:

pageNumberCurrent page
totalPagesTotal pages
datePrint date
titleThe document’s <title>
urlDocument URL
Request body
{
  "html": "<h1>Quarterly report</h1>…",
  "format": "A4",
  "margin": {
    "top": "24mm",
    "bottom": "20mm",
    "left": "16mm",
    "right": "16mm"
  },
  "headerHtml": "<div style=\"font-size:9px;width:100%;padding:0 16mm;display:flex;justify-content:space-between\"><span>Example Ltd</span><span class=\"title\"></span></div>",
  "footerHtml": "<div style=\"font-size:9px;width:100%;padding:0 16mm;text-align:right\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
}

The three quirks

  1. Set a font size. Header and footer text defaults to a tiny size and ignores your page’s stylesheet. Put styles inline, including font-size and font-family.
  2. Make room with margins. Headers and footers draw inside the page margin. With a zero top margin the header is invisible. Around 20–25 mm top and bottom fits one line comfortably.
  3. Images must be inline. The header context can’t fetch URLs. Use a data: URI or an inline<svg> for a logo.

Tables across pages

Chromium repeats <thead> on every page when a table breaks. Keep rows whole and avoid orphaned headings:

print.css
tr, .card { break-inside: avoid; }
h2, h3 { break-after: avoid; }
.page-break { break-before: page; }
thead { display: table-header-group; }
tfoot { display: table-footer-group; }

Different first page

Chromium applies the same header and footer to every page. For a cover page without them, render the cover and the body as two requests and merge them with a library such as pdf-lib, or design the header so it reads well on the cover too.

The report template uses all of the above. Its header and footer are attached when you render the built-in report id.