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.
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.
Print CSS and page layout
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.


