The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →The correct method depends on the PDF renderer. Puppeteer/Chromium uses HTML templates, wkhtmltopdf uses command-line options or separate HTML files, and paged-media engines such as WeasyPrint and Prince use CSS page-margin boxes, counters, and running content. Identify the renderer and its deployed version first, reserve space with page margins, then inspect a multi-page PDF for overlap, clipping, and incorrect page numbering.
Choose the renderer’s native header and footer mechanism
There is no single portable HTML-to-PDF recipe. Header support, page-number variables, first-page rules, and running titles differ between engines and releases. Confirm the binary, library, or browser version that actually creates your files before choosing an implementation.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
PDF Explained: The ISO Standard for Document Exchange | $14.41 | Buy on Amazon |
| 2 |
|
Adobe Acrobat 6 PDF For Dummies | $13.00 | Buy on Amazon |
| 3 |
|
Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware... | $13.39 | Buy on Amazon |
| Renderer | Primary mechanism | Page-number source | Important layout control |
|---|---|---|---|
| Puppeteer / Chromium | headerTemplate and footerTemplate in Page.pdf() |
Template classes such as pageNumber and totalPages |
PDF margin; displayHeaderFooter is off by default |
| wkhtmltopdf | --header-*, --footer*, or external HTML |
Substitutions such as [page] and [topage] |
Top/bottom margins and header/footer spacing |
| WeasyPrint | CSS @page margin boxes, counters, running elements, and named strings |
CSS counters and generated content | Supported CSS Paged Media features in the installed release |
| Prince | CSS @page margin boxes and generated content |
CSS counters such as counter(page) |
Named pages, facing-page rules, and page-specific selectors |
The distinctions above describe documented features, not a speed or cost ranking. Use the implementation that matches the engine already in your application.
Puppeteer: HTML templates with page numbers
Puppeteer’s Page.pdf() generates a PDF with the print CSS media type. Header and footer rendering is disabled unless you set displayHeaderFooter: true. Templates are HTML strings, and Puppeteer replaces documented classes with values at render time: date, title, url, pageNumber, and totalPages.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall#1 Best Overall
Reserve enough top and bottom margin for the template. A header that is taller than the reserved area can overlap the body; a footer can be clipped at the page edge.
Complete Node.js example
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com/report', { waitUntil: 'networkidle0' });
await page.pdf({
path: 'report.pdf',
format: 'A4',
printBackground: true,
displayHeaderFooter: true,
margin: {
top: '72px',
right: '36px',
bottom: '60px',
left: '36px'
},
headerTemplate: `
<div style="width:100%;font-size:9px;padding:0 36px;color:#555;">
<span>Acme report</span>
<span style="float:right"><span class="date"></span></span>
</div>`,
footerTemplate: `
<div style="width:100%;font-size:9px;padding:0 36px;color:#555;text-align:center;">
Page <span class="pageNumber"></span> of <span class="totalPages"></span>
</div>`
});
await browser.close();
})();
Template CSS is deliberately self-contained. Do not assume your page stylesheet will style the header or footer. If the source page has a dark theme or exact brand colors, remember that Chromium modifies colors for print by default; use -webkit-print-color-adjust: exact in the page stylesheet when matching screen colors is required. Puppeteer documents this behavior in its Page.pdf() reference.
Screen media versus print media
For a print-oriented PDF, leave the default print media type and define @media print rules. If the PDF must match the screen layout, call await page.emulateMediaType('screen') before page.pdf(). This changes the page’s media queries; it does not remove the need to reserve header and footer space.
Use the current Puppeteer PDFOptions documentation for the exact option names supported by your installed version. The search documentation identified version 25.12.0, but your project may use another release.
Free tools Windows power users keep installed
One-click scans. No signup required.
wkhtmltopdf: substitutions, options, and external HTML
wkhtmltopdf can add headers and footers with command-line arguments. Its usage documentation states: “Headers and footers can be added to the document by the –header-* and –footer* arguments respectively.” Text substitutions include [page] for the current page, [topage] for the last page, [title], and [doctitle].
Text header and footer
wkhtmltopdf
--margin-top 25mm
--margin-bottom 18mm
--header-left "Acme report"
--header-right "[title]"
--header-font-name Arial
--header-font-size 9
--header-spacing 4
--footer-center "Page [page] of [topage]"
--footer-font-name Arial
--footer-font-size 9
input.html report.pdf
Header spacing is not a replacement for a page margin. Increase --margin-top or --margin-bottom when the rendered header or footer approaches the body. The page settings reference documents header HTML URLs, spacing, and top/bottom margins.
External HTML templates
wkhtmltopdf
--margin-top 30mm
--margin-bottom 22mm
--header-html header.html
--footer-html footer.html
input.html report.pdf
In an external template, keep markup small and avoid assets that load slowly or require scripts unavailable to the renderer. Use the documented substitutions in the template where supported, and verify the installed wkhtmltopdf build because its documentation has older crawl dates and behavior can vary by deployment.
WeasyPrint: CSS page-margin boxes and running content
WeasyPrint documents CSS Paged Media support for @page, margin boxes, and page counters. It also supports running elements and named strings, which can carry a chapter heading into a page border.
@page {
size: A4;
margin: 25mm 18mm 20mm;
@top-center {
content: "Acme report";
font-size: 9pt;
color: #555;
}
@bottom-right {
content: "Page " counter(page) " of " counter(pages);
font-size: 9pt;
color: #555;
}
}
h1 { string-set: section-title content(); }
@page chapter {
@top-left { content: string(section-title); }
}
.chapter { page: chapter; }
Advanced Generated Content for Paged Media (GCPM) behavior is subject to implementation limits. Check the supported-features reference for the release installed in your environment before relying on a particular running-element or named-string feature.
Rank #2
Prince: generated content in page margins
Prince places generated content in @page margin boxes. A minimal footer is:
@page {
margin: 22mm 18mm 18mm;
@bottom-center {
content: "Page " counter(page);
font-size: 9pt;
}
}
Prince’s paged-media documentation also covers suppressing a footer on a title page and using different running headers on left- and right-facing pages. Its Paged Media documentation and User Guide describe the broader HTML/XML-to-PDF workflow.
Designing reliable headers and footers
Reserve usable body area
- Measure the actual rendered header and footer, including line wrapping and logos.
- Set top and bottom margins larger than those measurements, leaving a small safety gap.
- Keep header/footer content out of the document flow when the engine provides margin boxes or templates.
Handle first and last pages deliberately
A title page may need no header or a different footer. CSS engines can use page selectors or named pages; Prince documents page-specific examples. In Puppeteer, one template applies to the generated document, so put conditional first-page content in the document itself or generate separate sections/PDFs when necessary.
Make page numbers meaningful
Use the renderer’s documented mechanism rather than JavaScript that guesses page counts. Puppeteer injects pageNumber and totalPages; wkhtmltopdf substitutes [page] and [topage]; CSS engines use counters where supported.
Validate print styling
PDF generation may apply print media rules, hide screen-only elements, and alter colors. Check background images, font loading, and contrast under the renderer’s print mode. A browser preview is not proof that the PDF uses the same styles.
A repeatable validation workflow
- Record the exact renderer and version used in production.
- Create a fixture that spans at least three pages, includes a long heading, a table, an image, and a forced page break.
- Render with the intended paper size, margins, header, and footer.
- Inspect page one, a middle page, and the final page for overlap, clipping, missing assets, and page-number values.
- Repeat with unusually long titles and slow-loading resources; these expose wrapping and timing defects.
- Compare output after dependency upgrades, because CSS and template support can change between releases.
Troubleshooting common failures
Header or footer is missing
In Puppeteer, check that displayHeaderFooter is true and that the template is non-empty. In wkhtmltopdf, verify the relevant --header-*, --footer*, or --header-html/--footer-html option. In CSS engines, confirm that your installed release supports the margin box you selected.
Body text overlaps the header
Increase the corresponding PDF or @page margin. For wkhtmltopdf, increase the top margin as well as header spacing; spacing alone does not create body area.
Page numbers show literal text
Use the engine’s syntax exactly: Puppeteer’s classes, wkhtmltopdf’s bracket substitutions, or CSS counters. A class such as pageNumber has no special meaning in wkhtmltopdf, and [page] is not a CSS counter.
Colors differ from the browser
Puppeteer prints with print media and modifies colors for printing by default. Add -webkit-print-color-adjust: exact when appropriate, and ensure printBackground: true is set if backgrounds are required.
Rank #3
- Used Book in Good Condition
Footer works on page one but clips later
Render a multi-page fixture and inspect the longest footer line. Wrapping, font substitution, and different page content can expose a margin that was only large enough for the first page.
Images or fonts are absent
Wait for the renderer’s documented load condition, use absolute or accessible URLs, and check authentication headers and certificates. External HTML header/footer files may have a different base URL and permissions from the main document.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteOr skip the browser setup
ScreenshotNeo can return a PDF from one request, while handling the capture browser for you. Its clean-shot flow accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
For PDF-specific paper size, margins, landscape mode, page ranges, headers, or footers, send the relevant API parameters described in the ScreenshotNeo documentation. The basic request pattern is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan. Create a free ScreenshotNeo account.
Cost, caching, and operational considerations
- Browser rendering gives the most direct control over templates and CSS but requires managing Chromium or a converter binary, fonts, assets, timeouts, and upgrades.
- CSS paged-media engines are well suited to running section titles and facing-page layouts, but feature support must be checked against the installed release.
- For repeat captures, use caching deliberately. ScreenshotNeo lets you choose a cache TTL and reports whether a response was a cache hit.
- For high-volume jobs, separate capture timeout handling from PDF delivery, log renderer versions, and retain a representative multi-page fixture for regression checks.
Frequently Asked Questions
Can one header/footer implementation work in every HTML-to-PDF engine?
No. Template variables, CSS margin boxes, and command-line substitutions are engine-specific, so portability requires separate adapters or a renderer-specific abstraction.
Recommended Free Tools
How do I show a chapter title in every page header?
Use running elements or named strings in a paged-media engine that supports them, or generate the title into each page’s header template in an application-controlled workflow.
Should page numbers start on the cover?
That is a document-design choice. Use a first-page rule or separate title-page handling where your renderer supports it, then verify the visible numbering on the first content page.
Are header and footer HTML included in the document’s accessibility structure?
Behavior varies by renderer and PDF tagging configuration. If tagged or accessible PDF is a requirement, verify the generated structure with an accessibility checker rather than assuming visual output is sufficient.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




