Margin boxes have a separate CSS world
Header/footer templates do not inherit the page stylesheet. Inline their font size, width and alignment instead of relying on application classes.
The page looks right on screen but printing changes colors, pagination and margin boxes. Chromium header/footer templates are separate documents with restricted styling, not ordinary elements from the page.
Backgrounds disappear, content overlaps the footer, position:fixed repeats unexpectedly, or page numbers render with the default tiny font.
<span class='pageNumber'> and <span class='totalPages'> in the template; arbitrary page scripts do not run there.Use print CSS for document layout and Chromium templates only for the margin content. Reserve physical space with PDF margins.
await page.setContent(html, { waitUntil: "load" });
await page.emulateMedia({ media: "print" });
await page.pdf({
path: "report.pdf",
format: "A4",
printBackground: true,
displayHeaderFooter: true,
margin: { top: "0.65in", bottom: "0.65in", left: "0.5in", right: "0.5in" },
headerTemplate: '<div style="font-size:8px;width:100%;text-align:center"><span class="title"></span></div>',
footerTemplate: '<div style="font-size:8px;width:100%;text-align:center"><span class="pageNumber"></span> / <span class="totalPages"></span></div>',
});The call above is small. Everything around it is the system — and the system is what you would be signing up to own.
Header/footer templates do not inherit the page stylesheet. Inline their font size, width and alignment instead of relying on application classes.
Chromium does not automatically push document content away from a tall header. The PDF margins are the layout contract.
A print stylesheet may hide navigation and reflow tables. Choose media_type explicitly and test the same value used in production.
Running page numbers are meaningful on paginated output. pdf_fit_one_page creates a custom single sheet and is a poor match for multi-page reports.
A real PDF with selectable page content, inline-styled running header/footer and Chromium's pageNumber, totalPages, date, title and url substitutions.
One successful, non-cached capture costs one credit. Failures, including platform failures, cost zero; cache hits cost zero.
A PDF option is sent with a non-PDF format or a template exceeds its byte budget.
HTTP 400 · terminal
Remote assets or readiness rules consume the print job budget.
HTTP 500 · retryable
Swap the example for a page you care about. The runner keeps every option from this guide, and carries the whole configuration into the playground — no retyping, no starting over.
Written by PageCapture Engineering. Reviewed by PageCapture PDF maintainers. Verified 2026-08-12 by running the published code against a fixture.
The new header/footer parameters are contract-tested, normalized into the render spec, included in cache identity and type-checked against Playwright's PDF options; recipe snippets pass syntax validation.
Sources support the browser and API behaviors named above. PageCapture-specific limits and billing are taken from the public contract; external sources are used for the underlying browser behavior.
Defines Chromium PDF options and header/footer template classes.
Defines page-oriented CSS concepts and fragmentation context.
Canonical public parameter names, types and limits.
Run application-owned markup without hosting a page.
Print an existing hosted page with the same PDF controls.
The parameter contract for both sides, and why a set header renders invisible.
Run the same PDF engine on content you paste, before wiring print CSS into a page.