Free tools Windows power users keep installed
One-click scans. No signup required.
Set printBackground: true in page.pdf(). Puppeteer leaves background graphics out by default. Then use print-specific CSS with print-color-adjust: exact (and its WebKit counterpart), define page geometry deliberately, and verify the generated PDF in the same Chromium environment you deploy. These settings solve different parts of the problem: one enables background painting, while the CSS properties ask Chrome to retain authored colors.
The minimal Puppeteer fix
This is the smallest useful configuration:
await page.pdf({
path: 'output.pdf',
printBackground: true,
preferCSSPageSize: true
});
printBackground is documented as false by default. Setting it to true tells Puppeteer to include CSS background graphics in the PDF. preferCSSPageSize is optional; use it when your CSS @page rule must control paper size instead of Puppeteer’s format, width, or height options. Both options are documented in the Puppeteer PDFOptions reference.
For a complete script, make sure the page has finished loading before calling pdf():
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
await page.pdf({
path: 'output.pdf',
format: 'A4',
printBackground: true,
preferCSSPageSize: true,
margin: {
top: '0',
right: '0',
bottom: '0',
left: '0'
}
});
await browser.close();
Replace the URL and margins with the layout your document actually needs. Zero margins can permit a background to reach the paper edge, but they also remove the inset space that protects readable content.
#1 Best Overall
Why backgrounds disappear
Puppeteer uses print media
Page.pdf() generates the document using the print CSS media type. Rules inside @media screen therefore do not necessarily apply. Put print-only colors and layout in @media print, or explicitly request screen styles before creating the PDF:
await page.emulateMediaType('screen');
await page.pdf({ path: 'screen-styled.pdf', printBackground: true });
Use screen emulation only when the PDF is intentionally a screen-style rendering. For a print layout, leave the default print media type and provide the required rules in @media print. See Puppeteer’s Page.pdf() documentation and its PDF generation guide.
Background inclusion and color adjustment are separate
printBackground controls whether backgrounds are painted into the PDF at all. Chrome may still alter colors for printing after that decision. On the elements carrying the background, request exact authored colors:
@media print {
html,
body,
.page-content {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}
Puppeteer specifically recommends -webkit-print-color-adjust: exact in its PDF method remarks. print-color-adjust is the standard property. Neither is an absolute override: MDN notes that user-agent controls allowing users to suppress colors or images take priority. Apply the declarations to the actual background-bearing element, not an unrelated ancestor, and expect differences between browser versions, operating-system print settings, and PDF viewers.
Rank #2
Make the background cover the intended page area
Use a page-sized wrapper for full-page color
A page background and a content-box background are not the same. If the color should extend across the sheet, give the element a page-sized role and remove unintended body margins:
@page {
size: A4;
margin: 0;
}
html,
body {
margin: 0;
padding: 0;
}
.page {
min-height: 297mm;
box-sizing: border-box;
background: #18324a;
color: white;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
@media print {
.page {
break-after: page;
}
}
The A4 height shown here is appropriate for a single A4 page in a simple example. For multi-page content, avoid forcing every section to a fixed height unless you control page breaks; otherwise content can overflow or leave unexpected blank areas. The @page reference explains page size and margin rules.
Keep readable content inset when needed
Full-bleed color and readable margins can coexist by putting the background on an outer wrapper and padding the inner content:
.page {
background: #f1eadb;
padding: 18mm;
box-sizing: border-box;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.page__content {
background: white;
padding: 10mm;
}
Do not assume a CSS box margin is equivalent to a PDF page margin. Puppeteer options, @page margins, element margins, and padding affect different stages of layout. If you set both Puppeteer margins and CSS page margins, inspect the result for doubled whitespace.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsResolve paper-size and margin conflicts
Puppeteer can choose paper geometry with format, width/height, and margin. CSS can choose it with @page. If CSS must win, set:
await page.pdf({
path: 'css-sized.pdf',
printBackground: true,
preferCSSPageSize: true
});
Without that flag, Puppeteer documents that CSS page size is scaled to fit the option-selected paper. Do not combine an A4 @page rule with a conflicting format: 'Letter' and then infer that a missing edge background is a color problem; scaling and margins can move the painted area. Choose one source of truth, or explicitly give CSS precedence.
Landscape and custom dimensions
For a CSS-controlled landscape document:
@page {
size: A4 landscape;
margin: 8mm;
}
await page.pdf({
path: 'landscape.pdf',
printBackground: true,
preferCSSPageSize: true
});
Alternatively, use Puppeteer’s landscape: true and explicit dimensions. Do not specify contradictory values unless you have a reason to test the precedence in your exact Puppeteer and Chromium versions.
A reliable debugging sequence
- Confirm the page and stylesheet. Save the URL or HTML you expect, and ensure the print stylesheet is loaded before calling
pdf(). - Enable graphics. Add
printBackground: trueand regenerate. This is the most common omission. - Check media rules. Move required declarations into
@media print, or callpage.emulateMediaType('screen')if screen styling is intentional. - Adjust the real element. Add both color-adjust properties to the element that paints the background. A declaration on a sibling cannot affect that sibling’s painting.
- Inspect geometry. Temporarily set Puppeteer margins and
@pagemargins to known values. Remove duplicate body margins and check whetherpreferCSSPageSizeis required. - Check coverage. Confirm that the colored element actually spans the area you expect. A short content element will not automatically paint the rest of a page.
- Open the PDF in another viewer. A preview crop or viewer rendering issue can make an edge look white even when the PDF page box is correct.
- Reduce the case. Keep one page, one background, and one stylesheet. Record Puppeteer and Chromium versions, then compare the minimal PDF with the production document.
Common symptoms and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| All colors and images are absent | Background graphics are disabled | Set printBackground: true. |
| Screen color appears, print color does not | PDF uses print media | Add @media print rules or intentionally emulate screen. |
| Background is present but lighter or altered | Chrome’s print color adjustment or a user preference | Use both exact color-adjust properties on the painted element; verify user and viewer settings. |
| White strip at an edge | Puppeteer or @page margin, body margin, or a wrapper that does not fill the page |
Inspect each margin separately, remove unintended body margins, and size the wrapper. |
| Content is scaled unexpectedly | Conflicting CSS and Puppeteer paper settings | Set preferCSSPageSize: true when CSS should control, or remove the conflicting @page rule. |
| Only some pages have color | Background belongs to a content element whose height or page breaks vary | Use a page wrapper, check break-after/break-before, and inspect each page’s layout. |
Performance, reliability, and cost considerations
PDF generation waits for the page to load and for your chosen readiness condition. networkidle0 can wait indefinitely on pages with persistent analytics or streaming connections; use a targeted selector wait or a bounded delay when that better represents readiness. Background preservation itself does not guarantee that web fonts, lazy images, or late JavaScript have finished. Make those dependencies deterministic before page.pdf().
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Rank #4
Keep the Puppeteer and Chromium versions recorded with your deployment. The current Puppeteer API documentation consulted for this guidance reports version 25.12.0, but output is not guaranteed to be identical across every Chromium build or downstream viewer. Treat the settings as configuration requests, then inspect PDFs produced by the runtime that matters.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If you need a rendered page image or PDF without maintaining a Puppeteer process, ScreenshotNeo provides a website screenshot API and MCP server. Its one-call endpoint can return PNG, JPEG, WebP, or PDF; PDF options include paper size, margins, landscape mode, and page ranges. It removes cookie-consent banners, newsletter popups, and chat widgets before capture, while bot checks, blank pages, timeouts, failed loads, and cache hits are not billed. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents such as Claude or Cursor. The free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots.
See the ScreenshotNeo documentation for all options. A direct PDF request can be made with the same endpoint:
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
For a regular screenshot, omit format=pdf or choose the image format documented for your request. The service reports page and billing status in X-Page-Verdict and X-Billed headers, so failed or non-clean captures are distinguishable.
Equivalent calls from Python and Node.js
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
await Bun.write('shot.webp', data);
Create a free ScreenshotNeo account to use the 1,000-shot monthly allowance with no card.
Best Value
- Used Book in Good Condition
Frequently asked questions
Does print-color-adjust: exact force edge-to-edge printing?
No. It requests exact colors for an element. Page size, margins, element coverage, browser behavior, and user preferences still determine the final PDF.
Should I use margin: 0 in both places?
Only if you intentionally want no page inset and have accounted for content readability. Otherwise choose either Puppeteer margins or CSS @page margins as your primary layout control.
Why does a background work in Chrome’s print preview but not in my PDF?
Compare the preview’s media mode, paper settings, and background-graphics preference with Puppeteer’s settings. Ensure the PDF call enables printBackground and that your print stylesheet is loaded.
Recommended Free Tools
Frequently Asked Questions
Can I preserve a background image as well as a solid color?
Yes. Background images are included by the same printBackground: true setting, subject to loading completion, element coverage, browser behavior, and user print preferences.
What should I record when a production PDF differs from local output?
Record the Puppeteer version, Chromium build, page URL or HTML, CSS, PDF options, media type, and the generated PDF. Reproduce with a minimal one-page case before changing production styles.
The Bottom Line
Use printBackground: true, style the actual background element for print with both color-adjust properties, and make page size and margins unambiguous. When CSS should define the paper, add preferCSSPageSize: true; then verify the PDF in your deployed Chromium and viewer.
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.




