PDF headers, footers and page numbers with CSS
Add running headers, footers and 'Page X of Y' numbering to API-generated PDFs using CSS @page margin boxes — no post-processing step.
Last updated
| Rendering engine | WeasyPrint — implements CSS Paged Media (@page margin boxes, page counters) |
|---|
pdfrender's engine (WeasyPrint) implements the CSS Paged Media spec, so repeating headers and footers are plain CSS — no separate header-HTML parameter, no post-processing:
<style>
@page {
margin: 25mm 20mm;
@top-center {
content: "ACME Ltd — Monthly report";
font-size: 9pt; color: #666;
}
@bottom-right {
content: "Page " counter(page) " of " counter(pages);
font-size: 9pt; color: #666;
}
}
</style>
<h1>Report</h1>
<p>Body content flows across pages; the margin boxes repeat on every page.</p>
POST that document to /v1/render as-is (see the
curl guide) and every page carries the header and
the Page X of Y footer.
Variations
There are sixteen margin boxes per page (@top-left,
@bottom-center, corners, …). Different first page? Use the :first
pseudo-class:
@page :first {
@top-center { content: none; } /* no header on the cover page */
}
counter(page) and counter(pages) are standard CSS counters — you can
reset page per chapter with counter-reset on a page break.
Try it free
Paste the example into the free browser tool to see it paginate, or try the API free — 100 renders a month, no card.
FAQ
- How do I add page numbers to a PDF generated from HTML?
- Use the CSS Paged Media counters inside an @page margin box: content: "Page " counter(page) " of " counter(pages). WeasyPrint resolves both counters at render time, so no post-processing step is needed.
- Can headers and footers differ between the first page and the rest?
- Yes. CSS Paged Media provides the :first, :left and :right page selectors, so you can leave the margin box empty on @page :first and set it on the rest.
- Why do my headers not appear?
- Margin-box content only renders if the corresponding @page margin reserves space for it. If margin-top is 0, a @top-center box has nowhere to draw.