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

Use page.pdf() with either a named format such as A4, explicit width and height, or a CSS @page rule. If CSS should control the physical page, set preferCSSPageSize: true. Puppeteer uses print media by default, so choose the media type, margins, orientation, scaling and font-wait behavior as separate decisions.

Choose who controls the page size

There are three reliable models. Pick one source of truth for each PDF rather than supplying conflicting settings.

Approach Code or CSS Best for Important behavior
Named format format: 'A4' Standard paper such as A4 or Letter format takes precedence over width and height when all are supplied.
Custom dimensions width: '8.5in', height: '11in' Tickets, cards, labels and other non-standard paper Use unit-bearing strings when the requirement is physical; numbers are also accepted by the API.
CSS page geometry @page { size: 5in 7in; } plus preferCSSPageSize: true Documents whose stylesheet owns pagination CSS size gets priority; without the preference, Puppeteer scales content to the PDFOptions paper size.

The official Page.pdf() documentation describes print-media output, while the PDFOptions reference defines size precedence and related controls. Documentation reflects the main branch accessed on September 29, 2026; verify the version installed in your application if behavior differs.

Prerequisites and a minimal working script

Install Puppeteer

In a new Node.js project, install Puppeteer:

npm install puppeteer

The package downloads a compatible browser during installation. If your deployment supplies its own Chrome or Chromium, use the corresponding executable configuration and test the installed version.

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

Generate a first PDF

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com', { waitUntil: 'networkidle0' });
    await page.pdf({
      path: 'output-a4.pdf',
      format: 'A4',
      printBackground: true,
      margin: { top: '12mm', right: '12mm', bottom: '12mm', left: '12mm' }
    });
  } finally {
    await browser.close();
  }
})();

page.goto() waits for the page you target; the PDF call then writes the file. In production, add an application-level timeout and handle navigation failures so the browser is always closed.

Standard paper sizes with format

Use a named format when your output must match a conventional sheet. The API documents Letter as the default if no format, width or height is provided. Orientation is controlled independently with landscape, which defaults to false.

await page.pdf({
  path: 'report-a4.pdf',
  format: 'A4',
  landscape: false,
  printBackground: true
});

For a landscape report:

await page.pdf({
  path: 'report-a4-landscape.pdf',
  format: 'A4',
  landscape: true,
  printBackground: true
});

Do not combine a format with contradictory width and height values. Because format wins, the explicit dimensions may appear to be ignored.

Custom width and height

For a receipt, label or custom stationery, provide both dimensions. Width and height accept strings with units or numbers; explicit units make physical intent clear.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.pdf({
  path: 'output-custom.pdf',
  width: '8.5in',
  height: '11in',
  margin: {
    top: '0.25in',
    right: '0.25in',
    bottom: '0.25in',
    left: '0.25in'
  },
  printBackground: true
});

Use CSS units such as in, mm, cm or px as appropriate. Keep the dimensions and margins compatible with the printable area your downstream printer or viewer expects.

Let CSS @page define the paper

CSS is useful when a component library or document stylesheet already owns pagination. Define the page size and margins, then opt into CSS precedence:

<style>
  @page {
    size: 5in 7in;
    margin: 12mm;
  }
  @media print {
    .screen-only { display: none; }
  }
</style>
await page.pdf({
  path: 'output-from-css.pdf',
  preferCSSPageSize: true,
  printBackground: true
});

The default for preferCSSPageSize is false. When it is false, Puppeteer scales the document to fit the paper size selected through PDFOptions. When true, the CSS @page size takes priority. Avoid maintaining a different size in both places unless you deliberately want a fallback.

Control print media, pagination and appearance

Print versus screen styles

Page.pdf() generates PDFs using the print CSS media type. If the screen layout is the one you need, set it immediately before generating the file:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.emulateMediaType('screen');
await page.pdf({ path: 'screen-styled.pdf', format: 'A4' });

Otherwise, keep the default print media and place PDF-specific rules in @media print.

Margins and backgrounds

Use the margin object for top, right, bottom and left values. printBackground: true preserves background colors and images that may be omitted by default.

Scale and page ranges

The documented scale range is 0.1 through 2. A value below 1 shrinks content; a value above 1 enlarges it and can increase overflow. pageRanges limits output to selected pages, for example:

await page.pdf({
  path: 'appendix.pdf',
  format: 'A4',
  pageRanges: '3-5',
  scale: 0.95
});

Fonts, headers and footers

waitForFonts defaults to true, helping ensure web fonts are ready before layout is captured. If pagination still changes between runs, wait for the specific font or content in your page before calling page.pdf(). Header and footer templates are enabled with displayHeaderFooter; configure their templates and reserve enough margin for them.

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

Reusable patterns

A4 portrait report

await page.pdf({
  path: 'report.pdf',
  format: 'A4',
  landscape: false,
  margin: { top: '15mm', right: '15mm', bottom: '15mm', left: '15mm' },
  printBackground: true,
  waitForFonts: true
});

US Letter landscape dashboard

await page.pdf({
  path: 'dashboard.pdf',
  format: 'Letter',
  landscape: true,
  margin: '10mm',
  printBackground: true
});

CSS-owned product card

await page.addStyleTag({
  content: '@page { size: 4in 6in; margin: 8mm; }'
});
await page.pdf({
  path: 'card.pdf',
  preferCSSPageSize: true,
  printBackground: true
});

Troubleshooting different page sizes

“Puppeteer ignores my CSS page size”

Check that the PDF call contains preferCSSPageSize: true. Without it, PDFOptions paper geometry remains authoritative and the content is scaled to fit.

Width and height appear to do nothing

Look for a format property in the same options object. The named format takes precedence. Remove the conflicting property or use only the format you intend.

The PDF has unexpected colors or missing backgrounds

PDF generation uses print media and may omit backgrounds. Add printBackground: true, then inspect your @media print rules. If you require screen styling, call page.emulateMediaType('screen') first.

Text or images are cut off

Reduce margins or scale, check for fixed-width elements wider than the selected paper, and inspect overflow rules. A landscape format may be more appropriate for wide tables. If CSS controls the page, verify that the @page dimensions and component widths use compatible units.

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.

Fonts change pagination

Allow fonts to finish loading. Keep waitForFonts: true (the documented default), and wait for a font-ready or content-ready condition before calling page.pdf(). A late font substitution can alter line wrapping and page breaks.

Only some pages are needed

Use pageRanges such as '1' or '2-4'. Confirm the final page count after layout changes; ranges are applied to the generated document.

Reliability and performance checklist

  • Use one page-size authority: format, explicit dimensions or CSS with preferCSSPageSize.
  • Wait for the content that determines layout, not merely for the initial DOM.
  • Set navigation and application timeouts appropriate to your workload.
  • Always close the browser in a finally block.
  • Reuse a browser process for batches, but create a fresh page per document to prevent state leaking between jobs.
  • Keep large images and unnecessary scripts out of print output; they increase rendering time and memory use.
  • Compare PDFs at the target paper size, orientation and viewer zoom. A visually similar browser tab is not proof that print layout matches.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

ScreenshotNeo provides a website capture API when you need a rendered page or PDF without maintaining Puppeteer. It accepts and removes cookie-consent banners, newsletter popups and chat widgets before capture; bot checks, blank pages and failed loads are not billed. Its MCP server gives Claude, Cursor and other MCP clients take_screenshot, get_page_info and capture_pdf tools.

For a direct image or PDF request, see the ScreenshotNeo API documentation. The supplied cURL example is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

The same request in 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)

And 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}`);

Every response identifies whether it was a clean page, a bot check, a blank page, a failed load or a cache hit through X-Page-Verdict and X-Billed headers. The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

FAQ

What is Puppeteer’s default paper size?

The PDFOptions documentation lists Letter as the default when no paper format or dimensions are supplied.

Can CSS and PDFOptions both specify a size?

Yes, but choose the precedence intentionally. With preferCSSPageSize: true, CSS wins; otherwise Puppeteer fits content to the PDFOptions paper size.

Does landscape change custom dimensions?

It changes orientation for the PDF output. For predictable custom geometry, set width and height deliberately and verify the resulting orientation in your target viewer.

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

Frequently Asked Questions

Can I use millimeters for a custom Puppeteer page?

Yes. Width, height and margin values accept unit-bearing strings such as mm, cm, in and px.

Why does my PDF look different from the browser window?

Puppeteer prints with the print media type by default. Use page.emulateMediaType('screen') for screen CSS, or define the intended appearance in print styles.

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.