Free tools Windows power users keep installed
One-click scans. No signup required.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Short answer: Puppeteer’s documented footerTemplate applies to the print footer on every PDF page. It supports pageNumber and totalPages classes, but the PDFOptions reference documents no condition for rendering the template only when the current page is the last page. If your content only needs to come after the document, put it at the end of the HTML flow. If it must sit on the physical bottom margin of the final sheet, determine the final pagination first and then use a separately validated render or PDF post-processing overlay.
What Puppeteer can and cannot do
Enable displayHeaderFooter to use a footer template. Its documented default is false. The template is HTML supplied through footerTemplate; Puppeteer exposes special classes such as pageNumber and totalPages for page numbering. The current reference (shown as Puppeteer 25.12.0 when consulted) does not list a last-page conditional or an expression that hides the template on all pages except the final one. See the official PDFOptions documentation.
That distinction matters because page.pdf() renders with the print CSS media type. Margins, page breaks, font metrics, images, and print-specific rules determine pagination; a footer string alone cannot know the final page before Chromium lays out the document. The Page.pdf() documentation describes this print-media behavior.
Choose the placement you actually need
| Goal | Recommended direction | Trade-off |
|---|---|---|
| Show a note, signature, or summary after the body in reading order | Add an element at the end of the source HTML and style it for print | It follows the content, but is not guaranteed to touch the bottom edge of the final sheet. |
| Place content at the bottom margin of the final PDF page only | Determine final pagination, then apply a last-page overlay or separately validated second render | Provides physical placement control, but adds complexity and must be repeated when content changes page count. |
Option 1: Put the content at the end of the HTML flow
Use this approach when “last page footer” means “the final section appears after everything else.” It is the most stable solution because normal document flow participates in the same print layout as the body.
#1 Best Overall
- INNOVATIVE CARTRIDGE-FREE PRINTING — No more dealing with lots of tiny ink cartridges; With this wireless document and photo printer each ink bottle set is equivalent to about 90 individual cartridges²
- LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; When you choose this combination printer, scanner and copier you can print up to 4,500 pages black/7,500 color³
- COLOR PRINTING — Up to 2 years of ink in the box4 (and with every replacement ink set) for fewer out-of-ink frustrations
- ZERO CARTRIDGE WASTE — By using an Epson EcoTank printer you can help reduce the amount of cartridge waste ending up in landfills
- HOME PRINTER DESIGNED FOR RELIABILITY — The Epson EcoTank ET-2800 All-in-One Supertank Color Printer creates vivid, detailed prints and documents thanks to Micro Piezo Heat-Free Technology; Fire off 10 ISO pages per minute1 to easily finish large jobs
Complete Puppeteer example
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const html = `
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
@page { size: A4; margin: 20mm 16mm 22mm; }
@media print {
body { font-family: Arial, sans-serif; color: #111; }
.last-content {
margin-top: 18mm;
break-inside: avoid;
page-break-inside: avoid;
border-top: 1px solid #999;
padding-top: 5mm;
}
}
</style>
</head>
<body>
<main>
<h1>Report</h1>
<p>Your document body goes here.</p>
<!-- additional content -->
</main>
<section class="last-content">
<strong>End note</strong>
<p>This section is last in reading order.</p>
</section>
</body>
</html>`;
await page.setContent(html, { waitUntil: 'networkidle0' });
await page.pdf({
path: 'report.pdf',
format: 'A4',
printBackground: true,
preferCSSPageSize: true,
displayHeaderFooter: false
});
await browser.close();
})();
The section may begin on the final page or, if it does not fit, flow onto a new page. break-inside: avoid asks Chromium to keep the block together; it cannot override a block that is taller than a page. Use break-before: page when the ending section must always start on a fresh page, accepting that the preceding page may have unused space.
Reserve space and control print pagination
- Define margins in
@pageand keep the PDF options consistent with them. WithpreferCSSPageSize: true, CSS page size is used when available. - Use
@media printfor print-only rules. Puppeteer’s PDF path uses print media, not the screen media layout. - Wait for fonts and images before measuring or exporting. A late-loading image can change page count.
- Use
break-before,break-after, andbreak-insiderather than deprecated page-break properties where your browser support allows; retaining the older aliases can help compatibility.
Option 2: Use a regular footer template (for every page)
If a repeated footer is acceptable, this is the supported API. Keep the template self-contained and simple; the reference documents the page-number classes, not arbitrary JavaScript behavior inside the template.
await page.pdf({
path: 'report-with-footer.pdf',
format: 'A4',
printBackground: true,
displayHeaderFooter: true,
headerTemplate: '<span></span>',
footerTemplate: `
<div style="font-size:8px; width:100%; text-align:center;">
Page <span class="pageNumber"></span> of
<span class="totalPages"></span>
</div>`,
margin: { top: '20mm', right: '16mm', bottom: '22mm', left: '16mm' }
});
The bottom margin must leave room for the template. A community discussion in Puppeteer issue #5345 reports cases where insufficient margin affected visibility and where template text appeared too small to see. Those are practical reports, not guarantees about every version, so inspect your generated PDF.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Option 3: Two-pass rendering or PDF post-processing
When the content must be at the bottom edge of the final page and nowhere else, treat the task as pagination plus composition rather than a footer-template condition. There is no documented single-pass switch that means “render this template only when pageNumber == totalPages.”
Rank #2
- CARTRIDGE-FREE PRINTING — Print lab-quality photos, graphics and creative projects; Get vibrant colors and sharp text with Epson's high-accuracy printhead and Claria ET Premium 6-color inks
- INK BOTTLES — Save on photos1 and creative projects with affordable in-house printing; All-in-one printer allows you to print 4" x 6" photos for about 4 cents each vs. 40 cents with traditional ink cartridges1
- LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; Printer, scanner and copier lets you print up to 6,200 color pages³
- PRINT FOR LONGER — Up to 2 years of ink in the box² (and with every replacement ink set) for fewer out-of-ink frustrations with this wireless printer
- ZERO CARTRIDGE WASTE — Epson EcoTank printer helps reduce the amount of cartridge waste ending up in landfills; Cartridge-free printer uses high-yield ink bottles; Each replacement ink bottle set is equivalent to about 100 individual ink cartridges⁴
Two-pass outline
- Render the document without the final-page element. Use the production print CSS, fonts, images, page size, and margins.
- Determine the final page. Use a PDF parser, the renderer’s page count, or another deterministic inspection step. Do not infer it from source HTML length.
- Apply the final-page content. Generate an overlay positioned within the last page’s bottom margin, or render a second document whose dimensions and pagination are fixed to the first pass.
- Validate the merged PDF. Confirm that the overlay appears once, on the intended page, and is not clipped or covered by body content.
The exact overlay library and coordinate system depend on your PDF stack. A second render can change pagination if fonts, dimensions, or margins differ, so keep those inputs identical. If content changes after the first pass, repeat the pagination step.
Why a CSS-only fixed footer is risky
A print rule such as position: fixed; bottom: 0 can produce repeating content in Chromium’s paged output, and behavior varies with layout structure. It does not provide a documented “last page only” selector. Use it only after testing the exact Chromium and Puppeteer versions you deploy, and never assume that a screen preview predicts the PDF.
Reliable implementation workflow
- Define the requirement. Decide whether “footer” means end-of-flow content or a physical bottom-margin overlay.
- Freeze print inputs. Set page size, margins, fonts, image dimensions, and print color behavior. Use
page.emulateMediaType('print')only when you need to inspect print styling before PDF generation;page.pdf()itself uses print media. - Wait for assets. Use
page.setContent(..., {waitUntil: 'networkidle0'})where appropriate and explicitly await web fonts or application-specific readiness signals. - Generate a diagnostic PDF. Temporarily include page numbers, outlines, or a visible boundary around the final section so pagination can be inspected.
- Test multiple lengths. Test a one-page document, a document ending exactly at a page boundary, a long document, and content with images or tables that grow after load.
- Inspect the final artifact. Check page count, clipping, overlap, font size, and whether the ending content appears exactly once.
Troubleshooting
The footer appears on every page
That is the documented behavior of footerTemplate. Move the one-time content into the HTML flow, or implement a separately validated last-page overlay. A page-number class does not create a conditional.
The ending block is not on the final page
It may not fit in the remaining printable area. Reduce its height, reserve space, add break-before: page, or accept that normal flow places it on the next page. Check print margins and loaded fonts before changing CSS.
Rank #3
- SET IT UP ONCE AND PRINT WITH CONFIDENCE. No complicated maintenance. Just easy, reliable printing you can count on.
- INK FOR YEARS. NOT MONTHS. Up to 2 years of ink included. Get thousands of pages of cartridge-free printing. More pages, less hassle
- KEEPS PRINTING WELL AFTER COMPETITORS HAVE QUIT. No complex maintenance. Sharper text, richer colors.[2] Only with HP Smart Tank
- PREMIUM SUPPORT - Strong technical expertise to solve issues faster
- THE LAST PRINTER YOU'LL EVER NEED. Enjoy years of refillable, cartridge-free printing.
The footer is clipped or invisible
Increase the bottom margin, simplify the template, and verify its font size and color. The issue discussion cited above includes reports of margin-related visibility problems and text that was too small.
The page count changes between runs
Look for nondeterministic content: web fonts, responsive widths, timestamps, ads, animations, lazy images, or network responses. Wait for a deterministic readiness condition, disable animations for print, set image dimensions, and use a stable browser version.
CSS page breaks are ignored
Confirm that the rules are inside @media print, that selectors match the generated DOM, and that the element is not inside a layout context that prevents the break. Check the PDF rather than relying on a screen screenshot.
The overlay is on the wrong physical page
Do not reuse coordinates from a different paper size, scale, margin, or PDF origin. Derive coordinates from the actual output and rerun the overlay whenever pagination inputs change.
Rank #4
- Wireless Bluetooth Printer: Portable thermal printer compatible with iPhone, Android phones, iPad and tablet computers via Bluetooth. For smartphones, please download the "Nada Print" App. You can also connect to laptops and computers for printing using a USB-C cable. (Note: Laptops and computers can only be connected via USB and require the installation of a driver first. Bluetooth connection is not supported.)
- No-ink printing: Only supports US Letter and A4 size thermal paper.(Doesn't support regular paper) The no-ink portable thermal printer uses direct thermal technology, requiring no ink, toner or ribbons, making it environmentally friendly, cost-effective and time-saving. The thermal printer package comes with a roll of US Letter thermal printing paper. Note: When installing the paper, remember to switch the paper size switch on APP
- Clear Print: NDYIN N80 portable thermal printer adopts high-definition printing technology, with a 203DPI resolution to provide you with clear printing results. This mobile printer is compatible with roll paper, folded paper and tattoo transfer paper, supporting printing from your mobile phone PDF, Word, pictures and web pages anytime and anywhere. It is recommended to use our NDYIN thermal paper to achieve good printing quality
- Portable wireless printer for travel: The thermal printer is equipped with a built-in 1500mAh rechargeable battery, which can print 160 sheets of 8.5" x 11" thermal paper after being fully charged. It weighs only 1.5 pounds and is compact in size. This ink-free portable printer can be easily carried in a backpack or briefcase! It is perfect for business travel, cars, small offices, construction sites, schools and homes. You can print documents, contracts, invoices and boarding passes anytime and anywhere
- The N80 thermal printer has a wide range of uses. The package includes the N80 printer, a roll of US Letter paper(7m/roll), a user manual, a guide card, a type-C soft cable and a type C adapter. Note: The charging adapter is not included. Special thermal paper is required for use; ordinary paper cannot be used. This ink-free portable thermal printer is suitable for various scenarios such as home, school, travel, office, and outdoor, meeting the printing needs of different groups of people. This tattoo template printer is also compatible with tattoo transfer paper, making it an ideal choice for tattoo art
Performance, reliability, and cost considerations
- Performance: waiting for network idle improves completeness but can delay pages that contain long-lived connections. An application-specific “report ready” signal is often more deterministic.
- Reliability: pin and test the Puppeteer/Chromium versions you ship. Print layout is sensitive to font files, browser updates, and content changes.
- Security: if HTML or URLs are user-controlled, restrict navigation and resource access, sanitize injected markup, and avoid exposing secrets through custom headers or page content.
- Debugging: save the intermediate PDF and the exact HTML/CSS inputs for failed jobs. Compare page count and bounding boxes before and after changes.
Or skip the browser setup
If your requirement is simply to capture a URL as an image or PDF rather than control Chromium pagination in your own process, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; 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 tools let Claude, Cursor, or another MCP client call take_screenshot, get_page_info, and capture_pdf.
For a direct PDF or image request, see the ScreenshotNeo API documentation:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo includes full-page capture, PDF paper-size and margin controls, page ranges, custom CSS and JavaScript, waits, cookies and headers, device presets, caching, signed links, asynchronous jobs, bulk capture, and an OpenAPI specification. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
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 →Frequently overlooked details
- “Last page” is an output property. It cannot be safely determined from the source DOM before print layout.
- Page numbering is not a condition.
pageNumberandtotalPagesdisplay values; the documented API does not expose an if/then template mechanism. - Margins belong to the PDF contract. A footer that fits on screen can be clipped in the printable area.
- Validation is part of the feature. Test short, long, boundary, image-heavy, and font-loading cases whenever the document can change.
Frequently Asked Questions
Can I use a JavaScript expression in footerTemplate to test whether pageNumber equals totalPages?
The documented Puppeteer PDFOptions reference does not provide a conditional expression API for footer templates. Treat page-number classes as display placeholders and use document flow or a separate overlay instead.
Does setting displayHeaderFooter to true make a footer last-page-only?
No. It enables the header and footer templates for PDF output; the template is intended as a print footer and is not documented as a final-page-only feature.
What is the safest solution for a signature at the end of a report?
Put the signature block at the end of the HTML flow, style it under print media, and use page-break rules if it must start on a new page. Choose an overlay workflow only when physical bottom-edge placement is mandatory.
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.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.

