Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Put 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Amazon Basics Multipurpose Copy Printer Paper, 8.5 x 11 Inches, 20 lb, 92 Bright, White, 1 Ream (500 Sheets), Jam-Free
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 Printer Paper | 8.5 x 11 Paper | Copy &Print 20 lb | 1 Ream Case - 500 Sheets| 92 Bright | FSC Certified | 200060
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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
Amazon Basics Multipurpose Copy Printer Paper, 20 lb, 8.5 x 11 Inches, 3 Reams (1,500 Sheets), 92 Bright White for Home Use
  • 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 printBackground is 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“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
Amazon Basics Multipurpose Copy Printer Paper, 20 lb, 8.5 x 11 Inches, 5 Reams (2,500 Sheets), 92 Bright White
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“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.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Amazon Basics Multipurpose Copy Printer Paper, 20 lb, 8.5 x 11 Inches, 8 Reams (4,000 Sheets), 92 Bright White, Great for Crisp Ink Printing
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

Bestseller No. 1
Amazon Basics Multipurpose Copy Printer Paper, 8.5 x 11 Inches, 20 lb, 92 Bright, White, 1 Ream (500 Sheets), Jam-Free
Amazon Basics Multipurpose Copy Printer Paper, 8.5 x 11 Inches, 20 lb, 92 Bright, White, 1 Ream (500 Sheets), Jam-Free
1 ream (500 sheets) of 8.5 x 11 white copier and printer paper for home or office use; Virgin copy paper providing professional quality results; acid-free to prevent yellowing
$6.97
Bestseller No. 2
HP Printer Paper | 8.5 x 11 Paper | Copy &Print 20 lb | 1 Ream Case - 500 Sheets| 92 Bright | FSC Certified | 200060
HP Printer Paper | 8.5 x 11 Paper | Copy &Print 20 lb | 1 Ream Case - 500 Sheets| 92 Bright | FSC Certified | 200060
Sheet size – 8.5 x 11; Thickness – 20 pounds; Brightness – 92 bright white
$6.97
Bestseller No. 3
Amazon Basics Multipurpose Copy Printer Paper, 20 lb, 8.5 x 11 Inches, 3 Reams (1,500 Sheets), 92 Bright White for Home Use
Amazon Basics Multipurpose Copy Printer Paper, 20 lb, 8.5 x 11 Inches, 3 Reams (1,500 Sheets), 92 Bright White for Home Use
Virgin copy paper providing professional quality results; acid-free to prevent yellowing
$21.96
Bestseller No. 4
Amazon Basics Multipurpose Copy Printer Paper, 20 lb, 8.5 x 11 Inches, 5 Reams (2,500 Sheets), 92 Bright White
Amazon Basics Multipurpose Copy Printer Paper, 20 lb, 8.5 x 11 Inches, 5 Reams (2,500 Sheets), 92 Bright White
Virgin copy paper providing professional quality results; acid-free to prevent yellowing
$29.14
Bestseller No. 5
Amazon Basics Multipurpose Copy Printer Paper, 20 lb, 8.5 x 11 Inches, 8 Reams (4,000 Sheets), 92 Bright White, Great for Crisp Ink Printing
Amazon Basics Multipurpose Copy Printer Paper, 20 lb, 8.5 x 11 Inches, 8 Reams (4,000 Sheets), 92 Bright White, Great for Crisp Ink Printing
Virgin copy paper providing professional quality results; acid-free to prevent yellowing
$53.19

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.