ScreenshotNeo

BlogHTML to image & PDF

How to Set Margins When Generating PDFs with Puppeteer

Set independent PDF margins in Puppeteer with page.pdf(). Learn how page size and print CSS affect the result, plus common fixes.

By the ScreenshotNeo team4 October 20266 min read

Set PDF margins in Puppeteer by passing a margin object to page.pdf(). Give it any combination of top, right, bottom, and left; each value can be a string or number. Puppeteer documents the default as no margins. For a physical measurement, use a string with an explicit unit such as '20mm' or '0.5in'. Puppeteer PDFOptions and PDFMargin describe these settings.

Runnable example: generate a PDF with margins

This Node.js example launches Chromium, loads a page, and writes an A4 PDF with different horizontal and vertical margins. Install Puppeteer with npm install puppeteer, then save this as make-pdf.js and run node make-pdf.js.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.setContent(`
      <!doctype html>
      <html>
        <head>
          <meta charset="utf-8">
          <style>
            body { font: 16px/1.5 sans-serif; }
            h1 { margin-top: 0; }
          </style>
        </head>
        <body>
          <h1>Quarterly report</h1>
          <p>This page will be saved as a PDF.</p>
        </body>
      </html>
    `);

    await page.pdf({
      path: 'output.pdf',
      format: 'A4',
      printBackground: true,
      margin: {
        top: '20mm',
        right: '15mm',
        bottom: '20mm',
        left: '15mm',
      },
    });
  } finally {
    await browser.close();
  }
})();

The margin object controls each edge independently. This example is illustrative; choose measurements that suit the document and verify the resulting layout in your deployed Puppeteer and Chrome versions.

Choose page size and margins together

Margins are measured within the page you choose, so decide on the paper size before tuning the edges. Puppeteer defaults to Letter paper. Its documented dimensions are Letter at 8.5 × 11 inches and A4 at 210 × 297 millimeters. See the PaperFormat type for available named formats.

Need PDF options Effect
A named paper standard format: 'A4' or format: 'Letter' Selects a named format. If format is set, it takes priority over width and height.
A custom page size width and height Sets dimensions when a named format is not taking precedence.
Page size from the print stylesheet preferCSSPageSize: true Lets CSS @page size take priority over width, height, or format.

preferCSSPageSize defaults to false. At that setting, CSS @page size is scaled to fit the paper size specified in the PDF options. These rules describe page-size selection; they do not establish a universal precedence rule for conflicts between the API margin option and CSS @page { margin: ... }. If both declare margins, check the output with the Puppeteer and Chrome versions you deploy.

Equal margins

For a simple document with the same inset on every side, provide the same value for all four edges:

await page.pdf({
  format: 'Letter',
  margin: {
    top: '0.5in',
    right: '0.5in',
    bottom: '0.5in',
    left: '0.5in',
  },
});

Different margins by edge

Use separate values when the layout needs more room for a header, footer, or binding edge. For example, increase left for a bound report or bottom to reserve space at the foot of each page. The right values depend on the document design and output requirements.

page.pdf() renders using print CSS media. A site can therefore look different in its PDF than it does in a normal browser window: print styles may hide elements, change widths, or declare page rules. Puppeteer documents that PDF output uses print media in its Page.pdf() method.

If you specifically want screen styles in the PDF, set the media type before calling page.pdf():

await page.emulateMediaType('screen');
await page.pdf({
  path: 'screen-styled.pdf',
  format: 'A4',
  margin: { top: '12mm', right: '12mm', bottom: '12mm', left: '12mm' },
});

Use screen media only when that is the intended output. For documents designed for printing, inspect and adjust the print stylesheet instead. When CSS sets page dimensions, use preferCSSPageSize: true if the CSS page size should take priority; verify margin interactions separately.

Margins, headers, and footers

The four margin fields provide space at the page edges, but the document’s content and print styles still affect what fits in that space. When a header or footer needs its own reserved area, choose top or bottom margins that leave room for it and inspect multi-page output. Avoid assuming that a CSS @page margin and the API margin option combine in a particular way: the cited API references do not define a general conflict rule.

Troubleshooting Puppeteer PDF margins

Symptom Likely cause What to check
There is no whitespace around the page content No margin was supplied; the documented default is undefined, meaning no margins are set. Pass all four desired edges in the margin object.
The output uses the wrong paper dimensions format takes priority over width and height, or the PDF is using its default Letter format. Choose one intended page-size source and set it explicitly.
The CSS page size seems ignored or scaled preferCSSPageSize defaults to false, so CSS page size is scaled to fit the PDF option size. Set preferCSSPageSize: true if CSS @page size should take priority.
The PDF layout differs from the browser screen page.pdf() uses print media by default, so print CSS can change rendering. Review print styles, or call page.emulateMediaType('screen') before PDF generation if screen styling is intended.
Changing API and CSS margins gives an unexpected result The consulted API references do not define a general precedence rule for conflicting API and CSS margins. Test the exact combination with the Puppeteer and Chrome versions used by your application; avoid declaring conflicting margins where possible.
Margins look inconsistent between pages Content, page breaks, and print layout may make the remaining content area behave differently across pages. Inspect a multi-page PDF and check the print stylesheet and page-size settings alongside all four edge values.

Performance, reliability, and cost

Margin settings themselves are a small part of PDF generation. The larger practical concern is getting consistent output from the page content, print CSS, paper size, and the browser version used by the application. Keep those inputs explicit, use a fixed paper size when the document requires one, and review representative short and multi-page documents after changing layout rules. This is guidance, not a benchmark; the available sources provide no performance figures for margin choices.

For repeated generation, ensure each request closes its browser or reuses browser resources under a deliberate lifecycle policy. Handle navigation and rendering failures in the surrounding application, and do not treat a successful call as proof that the visual layout meets your document requirements. Puppeteer margin options do not carry a separate fee; compute and hosting costs depend on your own runtime and infrastructure.

Or skip the browser setup

If your goal is to capture a webpage as a PDF without managing a Puppeteer browser, ScreenshotNeo provides a screenshot API and MCP server. Its API supports PDF output and page margins. See the ScreenshotNeo documentation for the PDF parameters and current request details.

One GET request can return a PDF. This example uses the documented ScreenshotNeo endpoint and request pattern; set the PDF options supported by the API as described in its docs:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -d format=pdf \
  -o page.pdf

ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and responses say what happened in X-Page-Verdict and X-Billed headers. Its MCP server gives AI agents tools named take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to get started.

FAQ

What is the default margin for Puppeteer PDFs?

The documented margin default is undefined, which means no margins are set.

Can I set only one margin edge?

Yes. The four fields are optional. Specify the edges you need; set all four explicitly when you want a fully defined page inset.

Does Puppeteer default to A4?

No. Its default paper format is Letter. Set format or another page-size option when your output requires a different size.

Does Puppeteer use screen or print styles for a PDF?

It uses print CSS media by default. Call page.emulateMediaType('screen') first when screen styles are specifically required.