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 & 11Put the border on an element that is rendered in your Handlebars HTML, then let Puppeteer print that HTML with page.pdf(). Do not rely on @page { border: ... }: page-box border properties are not a generally supported browser feature. For borders that use fills, images, or other background graphics, set printBackground: true; it is false by default.
Use a rendered wrapper, not the CSS page box
Puppeteer generates a PDF by printing the page with the print CSS media type. The reliable place for a border is therefore an element in the document—usually a wrapper that represents one sheet of content, or a container around the document body. CSS @page remains useful for paper size, orientation, margins, and page-specific rules, but MDN lists border properties among page-box properties that user agents do not support. A declaration such as @page { border: 2px solid #222; } can be ignored.
An element border has an important limitation: CSS fragmentation determines how that element behaves when content flows onto another PDF page. A single long wrapper may have a border only around its overall box, while a repeating border on every physical sheet may require a page-oriented layout. Inspect the produced PDF for your actual content, browser version, and break points instead of assuming that a particular selector repeats perfectly.
A complete Handlebars and Puppeteer implementation
The example below creates an A4 PDF, gives each content sheet a visible border, and keeps template data escaped by using normal Handlebars expressions. It uses Node.js, Puppeteer, and Handlebars.
Recommended Free Tools
#1 Best Overall
- 1 ream (500 sheets) of 8.5 x 11 white copier and printer paper for home or office use
- Multipurpose letter size copy paper works with laser/inkjet printers, copiers and fax machines
- Smooth 20lb weight paper for consistent ink and toner distribution; dries quickly and resists paper jams
- Bright white paper (92 GE; 104 Euro) offers great contrast for crisp printing and vivid color
- Virgin copy paper providing professional quality results; acid-free to prevent yellowing
Install the packages
npm install puppeteer handlebars
Create the generator
const fs = require('node:fs/promises');
const Handlebars = require('handlebars');
const puppeteer = require('puppeteer');
const templateSource = `
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
@page {
size: A4;
margin: 18mm;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
font-family: Arial, sans-serif;
color: #222;
font-size: 11pt;
line-height: 1.45;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.sheet {
border: 1.5pt solid #1f2937;
padding: 12mm;
min-height: 257mm;
break-after: page;
}
.sheet:last-child { break-after: auto; }
h1 { margin: 0 0 8mm; font-size: 22pt; }
h2 { margin: 7mm 0 3mm; font-size: 14pt; }
p { margin: 0 0 4mm; }
.avoid-split { break-inside: avoid; }
</style>
</head>
<body>
{{#each sheets}}
<section class="sheet">
<h1>{{title}}</h1>
{{#each paragraphs}}
<p>{{this}}</p>
{{/each}}
{{#if note}}
<p class="avoid-split"><strong>Note:</strong> {{note}}</p>
{{/if}}
</section>
{{/each}}
</body>
</html>`;
const data = {
sheets: [
{
title: 'Project brief',
paragraphs: [
'This text is escaped by Handlebars before it is inserted into the HTML.',
'The border belongs to the rendered .sheet element, not to the @page rule.'
],
note: 'Long content can still require PDF inspection at page breaks.'
},
{
title: 'Implementation notes',
paragraphs: [
'A second section produces a second bordered sheet in this page-oriented layout.'
]
}
]
};
(async () => {
const template = Handlebars.compile(templateSource);
const html = template(data);
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.setContent(html, { waitUntil: 'networkidle0' });
await page.pdf({
path: 'bordered.pdf',
format: 'A4',
printBackground: true,
preferCSSPageSize: true
});
} finally {
await browser.close();
}
})();
Run it with node generate.js. The output is bordered.pdf. In this design, each .sheet is intentionally a page-sized section. break-after: page starts the next section on a new sheet, while break-inside: avoid helps keep a small note together. If your content is naturally one continuous article, remove the forced sections and use a border on the layout container—but verify how the border fragments across pages.
Adapt the border to your document
Simple border around flowing content
.document {
border: 1px solid #555;
padding: 10mm;
}
This is appropriate when one border around the document is the intended visual treatment. It does not guarantee a complete border on every physical PDF page when the element spans page breaks.
One bordered sheet per page
Render a repeated page wrapper from Handlebars, as in the example. Give the wrapper a height that fits inside the printable area after the @page margins, add break-after: page, and leave the final wrapper without a break. The available height depends on paper size, margins, border width, and padding; a value that fits A4 may clip on Letter.
Keep important blocks intact
Use break-inside: avoid on tables, callouts, signatures, or headings with their following paragraph. This is a request to the print engine, not an absolute guarantee. If a block is taller than a page, it must still split.
Use background graphics deliberately
If the border is a background image, gradient, or colored design rather than a normal border declaration, include printBackground: true. Puppeteer’s default is false, so the PDF can otherwise lose those graphics. The CSS -webkit-print-color-adjust: exact (and the standard print-color-adjust fallback) asks Chromium to preserve specified colors; print output can otherwise adjust them.
Rank #2
- HP Papers is sourced from renewable forest resources and has achieved production with 0% deforestation in North America. Each ream is wrapped in a polyurethane coated paper wrapper to protect the cut sheets from moisture damage
- Sheet size – 8.5 x 11; Thickness – 20 pounds; Brightness – 92 bright white
- HP Copy&Print20 20 pounds printer paper is Forest Stewardship Council (FSC) certified and contributes toward satisfying credit MR1 under LEED (Leadership in Energy and Environmental Design)
- All HP Papers provide premium performance on HP equipment, as well as on all other printer and copier equipment; 100% satisfaction guaranteed; ColorLok technology provides more vivid colors, bolder blacks and faster drying
- Superior quality, reliability, and dependability for high-volume printing at home, at school and in the office; HP Copy&Print20 print and copy paper prevents yellowing over time to ensure a long-lasting appearance for added archival quality
Control paper, margins, and CSS page size
Puppeteer’s PDF options let you choose a named format or explicit dimensions, margins, landscape mode, and background printing. In the example, format: 'A4' selects the paper. preferCSSPageSize: true allows a CSS @page size to take precedence when one is defined. When both a format and explicit width/height are supplied, the format takes priority. Choose one source of truth where possible, then measure the border against the resulting printable area.
Margins are outside the element’s border. A border placed at the edge of a wrapper cannot extend into the margin area unless the layout is designed for that. Increase the margin when the stroke is clipped, or reduce wrapper padding and minimum height. Test portrait and landscape separately; rotating the paper changes the usable dimensions.
Handle Handlebars data safely
Handlebars interpolates values from an input object and escapes normal expressions such as {{title}}. Keep that behavior for titles, paragraphs, URLs, and user-entered text. Triple-stash expressions such as {{{html}}} bypass escaping and should be reserved for HTML you control and sanitize. Handlebars does not escape JavaScript strings, so never treat a template as a substitute for validating scripts or other executable input.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
For trusted rich text, pass a separately sanitized HTML field and document that trust boundary. For untrusted content, render text nodes with normal expressions and add only the markup your template defines.
Inspect the actual PDF before shipping
Border continuity, clipping, overlap, and page-break behavior are rendering outcomes. Open the generated file in more than one PDF viewer and check:
Rank #3
- 3 ream case (1,500 sheets) of 8.5 x 11 white copier and printer paper for home or office use
- Multipurpose letter size copy paper works with laser/inkjet printers, copiers and fax machines
- Smooth 20lb weight paper for consistent ink and toner distribution; dries quickly and resists paper jams
- Bright white paper (92 GE; 104 Euro) offers great contrast for crisp printing and vivid color
- Virgin copy paper providing professional quality results; acid-free to prevent yellowing
- Every intended sheet has a complete stroke on all four sides.
- The border does not overlap headings, tables, footers, or images.
- Long paragraphs and tables break at sensible locations.
- Background colors and border colors appear when
printBackgroundis enabled. - The last page does not contain an unwanted blank sheet from a trailing page break.
- Fonts and remote images have loaded before
page.pdf()runs.
For deterministic output, wait for the page’s required network activity, use local or reliably hosted assets, and avoid measuring layout before fonts finish loading. If the document contains dynamic content, add an explicit readiness signal in the page and wait for it before printing.
Common failures and fixes
“The @page border is missing”
That is expected in browsers because page-box border properties are not a supported general route. Move the border to a rendered wrapper or repeated page section.
“The border appears on screen but not in the PDF”
Check that the rule is active under print media and that the border is not supplied by a background graphic. Add printBackground: true for backgrounds, and use print-specific CSS if a screen media query overrides the rule.
“Colors or a decorative frame disappear”
Enable printBackground: true and add -webkit-print-color-adjust: exact. Also confirm that the design is not relying on an external stylesheet or image that failed to load.
“The border is clipped at the edge”
Reduce the wrapper’s minimum height or padding, increase @page margins, or account for border width in the available height. Check the selected paper format and orientation.
Rank #4
- 5 ream case (2,500 sheets) of 8.5 x 11 white copier and printer paper for home or office use
- Multipurpose letter size copy paper works with laser/inkjet printers, copiers and fax machines
- Smooth 20lb weight paper for consistent ink and toner distribution; dries quickly and resists paper jams
- Bright white paper (92 GE; 104 Euro) offers great contrast for crisp printing and vivid color
- Virgin copy paper providing professional quality results; acid-free to prevent yellowing
“A long wrapper has a broken border across pages”
A border on one fragmented element is not equivalent to a per-sheet frame. Switch to explicit page-sized sections when every physical page must have four sides, or redesign the frame as a tested header/footer/background technique.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →“Content overlaps or starts on a blank page”
Look for forced break-before/break-after, oversized fixed heights, and margins that exceed the printable area. Remove the break from the final section and verify that each section can fit inside the selected page.
“Template data is interpreted as markup”
Replace triple-stash output with escaped expressions for untrusted values. If rich HTML is required, sanitize it before compilation and keep the trusted field separate from ordinary text data.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Performance, reliability, and cost considerations
Launching Chromium is the expensive part of a small batch, so reuse one browser process and create or close pages per job rather than launching a browser for every PDF. Wait only for the assets your document needs; a blanket network-idle wait can be slow on pages with analytics or long-lived connections. For repeatable server jobs, pin a Puppeteer/Chromium version, set timeouts, and log the input data identifier and output path.
PDF generation is memory-intensive for large images and many pages. Resize source images, avoid embedding unnecessary assets, and process large batches with a queue so concurrent jobs do not exhaust memory. Treat generated files as sensitive if the template contains private data, and delete temporary files according to your retention policy.
Best Value
- 8 ream case (4,000 sheets) of 8.5 x 11 white copier and printer paper for home or office use
- Multipurpose letter size copy paper works with laser/inkjet printers, copiers and fax machines
- Smooth 20lb weight paper for consistent ink and toner distribution; dries quickly and resists paper jams
- Bright white paper (92 GE; 104 Euro) offers great contrast for crisp printing and vivid color
- Virgin copy paper providing professional quality results; acid-free to prevent yellowing
Or skip the browser setup
If you only need a clean image or PDF capture of an existing URL rather than a custom Handlebars layout, ScreenshotNeo provides a website screenshot API and MCP server. Its preprocessing accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response reports the result in X-Page-Verdict and X-Billed headers.
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, viewport and device presets, full-page capture, CSS selectors, custom CSS or JavaScript, waiting rules, headers and cookies, geolocation, caching, signed links, asynchronous jobs, bulk capture, and usage details. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
FAQ
Does page.pdf() use screen CSS?
No. Puppeteer prints with the print media type, so inspect or define print-specific rules.
Can I guarantee a border on every PDF page with one CSS rule?
No. Repeating borders depend on layout fragmentation. Use explicit page sections when that requirement matters and verify the output.
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 minuteShould I always set preferCSSPageSize?
Only when your CSS @page size should control the result. Otherwise let the selected Puppeteer format or dimensions be authoritative.
Frequently Asked Questions
Can a CSS border be placed directly on the PDF page?
Not reliably through @page. Put the border on rendered HTML and test the generated PDF.
Why are my background colors absent?
Set printBackground: true and use print color adjustment CSS when exact colors are required.
How do I prevent unsafe Handlebars content?
Use escaped expressions for untrusted values; sanitize any trusted rich HTML before rendering.
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 →The Bottom Line
Render the frame in HTML, configure paper and print options explicitly, and inspect real PDFs at page breaks. That approach is dependable; an @page border is not.
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.

