For a Puppeteer PDF, the most compatible way to print “Page 1 of 8” is to enable displayHeaderFooter and put pageNumber and totalPages spans in footerTemplate. CSS @page margin-box counters are a separate option: they can place generated content in page margins in Chrome 131 and later, but support depends on the Chromium build that Puppeteer actually launches.
The reliable Puppeteer method: footerTemplate
Puppeteer’s Page.pdf() API recognizes a small set of classes in header and footer templates. Add displayHeaderFooter: true, reserve space with a bottom margin, and include elements whose classes are pageNumber and totalPages. Puppeteer fills those elements with the current page and document page count.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setContent(`
<main>
<h1>Quarterly report</h1>
<p>Your report content goes here. Add enough content to create multiple pages.</p>
</main>
`, { waitUntil: 'networkidle0' });
await page.pdf({
path: 'report.pdf',
format: 'A4',
printBackground: true,
displayHeaderFooter: true,
margin: {
top: '16mm',
right: '14mm',
bottom: '18mm',
left: '14mm'
},
footerTemplate: `
<div style="width:100%; font-size:9px; text-align:right; padding:0 12mm;">
<span class="pageNumber"></span> / <span class="totalPages"></span>
</div>
`
});
await browser.close();
The template is self-contained HTML. Inline styles are the safest choice because the footer is rendered separately from the page document’s normal stylesheet. The bottom margin must be large enough for the footer; otherwise text can overlap the body or be clipped.
What the injected classes mean
pageNumberdisplays the number of the page currently being rendered.totalPagesdisplays the total number of pages in the generated PDF.- Other markup in the template is ordinary HTML, so you can add a title, a rule, an image, or alignment wrappers.
Common footer layouts
footerTemplate: `
<div style="width:100%; font:9px Arial, sans-serif; display:flex; justify-content:space-between; padding:0 10mm;">
<span>Confidential</span>
<span>Page <span class="pageNumber"></span> of <span class="totalPages"></span></span>
</div>
`
Keep the footer’s height predictable. Large fonts, wrapping text, or external assets can change the available layout and make pagination appear different from the screen preview.
#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
How PDF media and margins affect the result
Page.pdf() renders with the print CSS media type by default. If your design is written for screen media, select it explicitly before generating the PDF:
await page.emulateMediaType('screen');
await page.pdf({
displayHeaderFooter: true,
footerTemplate: '<div>Page <span class="pageNumber"></span></div>',
margin: { bottom: '18mm' }
});
Use this only when screen styling is intentional. Otherwise, leave the default print media behavior in place and define print-specific rules with @media print.
Reserve space and control the paper size
- Set a bottom PDF margin for the footer. The margin is measured outside the document content area.
- Use
format: 'A4',format: 'Letter', or explicitwidthandheightas appropriate for your audience. - If your CSS contains an
@page { size: ... }declaration, setpreferCSSPageSize: truewhen that CSS size should override Puppeteer’sformat,width, orheightoptions. Its documented default isfalse.
await page.pdf({
path: 'custom-size.pdf',
displayHeaderFooter: true,
preferCSSPageSize: true,
margin: { top: '15mm', right: '15mm', bottom: '20mm', left: '15mm' },
footerTemplate: '<div style="text-align:center; width:100%; font-size:9px;">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>'
});
Using CSS counters in @page margin boxes
CSS Paged Media defines page-margin boxes and page counters. In a browser that implements them, you can write the footer in CSS rather than Puppeteer’s template:
@page {
size: A4;
margin: 16mm 14mm 20mm;
@bottom-center {
content: "Page " counter(page) " of " counter(pages);
font-size: 9pt;
font-family: Arial, sans-serif;
}
}
@media print {
body { margin: 0; }
}
counter(page) represents the current page, while counter(pages) represents the total page count. This is not the same mechanism as footerTemplate: it is CSS-generated content in a page-margin box, whereas Puppeteer’s placeholders are elements in an HTML template.
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
Check the Chromium version before depending on margin boxes
Chrome for Developers documents generated content in print margins beginning with Chrome 131. Puppeteer can use a bundled browser or a browser executable selected by your deployment, so the Puppeteer package version alone does not prove that margin boxes are available. Confirm the actual Chromium version in CI and production, and render a representative multi-page document before adopting this approach.
If you need broad compatibility across older or mixed browser builds, use displayHeaderFooter with footerTemplate. If CSS-defined placement is a hard requirement, pin and verify a Chromium version that supports the margin-box feature.
Choosing between the two techniques
| Requirement | Recommended technique | Reason |
|---|---|---|
| Works across more Puppeteer deployments | footerTemplate |
It is the documented Puppeteer API and uses recognized placeholders. |
| Footer HTML needs custom layout | footerTemplate |
You can provide a self-contained HTML fragment with inline styles. |
| Footer must be declared entirely in CSS | @page margin boxes |
CSS controls the margin position and generated content. |
| Browser versions are not tightly controlled | footerTemplate |
Margin-box behavior is dependent on the Chromium feature implementation. |
CSS @page sets the paper size |
Either, plus preferCSSPageSize: true when needed |
This option gives CSS page size priority over PDF size options. |
Validation checklist before shipping
- Generate a document with at least three pages, including a final page with little content.
- Confirm the first page shows
1and the last page’s total matches the PDF’s actual page count. - Inspect the bottom edge at normal and high zoom for clipping, overlap, and unexpectedly small text.
- Test long titles, narrow paper sizes, large fonts, tables, images, and pages created by forced breaks.
- Run the same code with the Chromium executable used in production; browser upgrades can alter pagination and CSS support.
- If the body overlaps the footer, increase the PDF bottom margin rather than adding arbitrary padding to the document.
Troubleshooting page numbers and CSS counters
The footer is missing
Ensure displayHeaderFooter: true is present in the same page.pdf() call as footerTemplate. The documented default is false. Also verify that the template is a non-empty HTML string.
The classes print literally
pageNumber and totalPages are recognized class names, not CSS counters. They must appear as class attributes on elements in footerTemplate, for example <span class="pageNumber"></span>. A typo, different capitalization, or putting the class only in the main document will not work.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
Numbers are clipped or overlap content
Increase margin.bottom, reduce footer font size, and keep the footer’s line height and padding predictable. Remember that footer space is not automatically reserved just because a template exists.
counter(page) stays empty
Your Chromium build may not implement CSS page-margin boxes, or the syntax may not be accepted in that build. Use the Puppeteer template method, or verify that the deployed browser meets the documented Chrome 131 threshold and that your CSS uses an @bottom-* margin box.
The page count changes after adding a footer
Pagination is sensitive to available space. A footer margin, different media type, font loading, or paper size can push content onto another page. Treat the final PDF—not a screen screenshot—as the source of truth, and test with production fonts and assets.
CSS page size is ignored
Set preferCSSPageSize: true when the @page size should win. With the default of false, Puppeteer’s explicit format, width, or height can take precedence.
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 minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
Performance and reliability considerations
- Wait for the content that determines pagination. Use
page.setContent()with an appropriatewaitUntilvalue, and await critical font or image loads before callingpage.pdf(). - Keep header and footer markup lightweight. External network requests in a footer can delay rendering or fail in restricted environments.
- Pin or explicitly select the Chromium executable in production so CSS feature behavior is reproducible.
- Store a sample PDF from each deployment and compare page count, footer position, and typography after Puppeteer or browser upgrades.
- Do not infer compatibility from a single successful local render; container images, operating-system fonts, and browser channels can differ.
Or skip the browser setup
If your goal is a clean screenshot or PDF capture rather than a custom Puppeteer footer, ScreenshotNeo provides a website screenshot API and MCP server. A single request can capture a URL, while its cleanup steps accept cookie and consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; response headers identify the page verdict and billing result.
For an image capture, the documented cURL 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
See the ScreenshotNeo API documentation for PDF options and the other capture parameters. The service also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. It supports full-page and element captures, device and viewport settings, dark mode, retina scale, custom CSS and JavaScript, click and wait actions, request blocking, cookies and headers, timezone and geolocation, caching, signed links, asynchronous webhooks, bulk capture, usage reporting, and HTML/CSS-to-image workflows.
Plans include 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account to try it.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →FAQ
Can I put a custom prefix such as “Page” in the Puppeteer footer?
Yes. Put the text beside the recognized spans in footerTemplate, such as Page <span class="pageNumber"></span>. Puppeteer supplies only the numeric values.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Does totalPages require a second PDF pass?
No. Puppeteer injects the total page count while rendering the PDF. A second pass is unnecessary for the documented template placeholders.
Should I use counter(pages) or totalPages?
Use totalPages in the Puppeteer footer template. Use counter(pages) only when you intentionally rely on CSS page-margin boxes and have verified browser support.
Why does a footer look different from the page’s CSS?
The footer template is a separate HTML fragment. Put its essential styles inline instead of assuming the main document’s stylesheets will apply.
Frequently Asked Questions
Can I put a custom prefix such as “Page” in the Puppeteer footer?
Yes. Put the text beside the recognized spans in footerTemplate, such as Page <span class="pageNumber"></span>. Puppeteer supplies only the numeric values.
Does totalPages require a second PDF pass?
No. Puppeteer injects the total page count while rendering the PDF.
Should I use counter(pages) or totalPages?
Use totalPages in the Puppeteer footer template unless you have verified CSS page-margin-box support in your Chromium build.
The Bottom Line
For dependable page numbers, use displayHeaderFooter, a self-contained footerTemplate, and a sufficient bottom margin. Reserve CSS @page counters for deployments where the actual Chromium version has verified margin-box support.
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.

