Use a headless Chromium browser from Node.js: navigate to the page, then call Puppeteer’s or Playwright’s page.pdf(). Both generate PDFs using print CSS by default. For a PDF that follows screen styling instead, explicitly emulate screen media before exporting.
Save a webpage as a PDF with Puppeteer
Install Puppeteer in your Node.js project, then run a script that opens a browser, loads the page, writes a PDF, and closes the browser. This follows the basic pattern in the Puppeteer PDF guide.
const puppeteer = require('puppeteer');
async function savePageAsPdf() {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://news.ycombinator.com', {
waitUntil: 'networkidle2',
});
await page.pdf({ path: 'page.pdf' });
} finally {
await browser.close();
}
}
savePageAsPdf().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Change the URL and output filename for your use case. The path option writes the PDF to a file relative to the process’s current working directory unless you supply an absolute path. Puppeteer’s PDF method returns PDF bytes as well as supporting file output. It waits for fonts to load by default.
Save a PDF with Playwright
Playwright’s equivalent uses Chromium, a page navigation, and page.pdf(). Its PDF export is Chromium-only; use the Chromium browser type for this workflow. See the Page API and PDF export documentation.
Free tools Windows power users keep installed
One-click scans. No signup required.
#1 Best Overall
const { chromium } = require('playwright');
async function savePageAsPdf() {
const browser = await chromium.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle',
});
const pdfBuffer = await page.pdf({ path: 'page.pdf' });
return pdfBuffer;
} finally {
await browser.close();
}
}
savePageAsPdf().catch((error) => {
console.error(error);
process.exitCode = 1;
});
With path, Playwright saves the file there; the method also returns a buffer containing the PDF. If you omit path, it returns the buffer without saving a file, so write that buffer yourself if you need a disk copy.
Choose print or screen styling
By default, both libraries render the page using print CSS media. A site may therefore hide navigation, change colors, or rearrange content in the PDF compared with its normal browser appearance.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Use print styles
Keep the default when the site has print-specific rules or when the goal is a document-friendly layout. Review the page’s @media print and @page rules if elements disappear or page breaks look unexpected.
Use screen styles
Switch the media type before generating the PDF when you want the page’s screen stylesheet instead.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Rank #3
// Puppeteer
await page.emulateMediaType('screen');
await page.pdf({ path: 'screen-layout.pdf' });
// Playwright
await page.emulateMedia({ media: 'screen' });
await page.pdf({ path: 'screen-layout.pdf' });
Control paper size, margins, and backgrounds
PDF options affect layout; they do not guarantee identical output across websites. Print CSS, the selected media type, the paper format, and margins all influence pagination.
- Paper size: Playwright accepts formats such as
LetterandA4. - Margins: Set them explicitly when you need predictable printable space around the page content.
- Backgrounds: Playwright does not print background graphics by default. Enable
printBackgroundwhen those colors or images are required. - CSS page size: CSS
@pagesizing does not take priority by default in Playwright; usepreferCSSPageSize: trueto prefer it. - Page ranges and scale: Playwright supports page ranges and scale controls for output that needs selected pages or adjusted sizing.
await page.pdf({
path: 'formatted.pdf',
format: 'A4',
margin: { top: '15mm', right: '12mm', bottom: '15mm', left: '12mm' },
printBackground: true,
preferCSSPageSize: true,
});
For Puppeteer, printed colors may be modified. Its documentation recommends -webkit-print-color-adjust in CSS when exact print colors matter; confirm the page’s print stylesheet rather than assuming screen colors will carry over.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Wait for the page content you need
Navigation completion is not the same as every page-specific operation being finished. A page can load more content asynchronously, such as after scripts run or a user interaction. The right readiness condition depends on the site; there is no universal wait that guarantees every dynamic page is complete.
Use a site-specific selector or observable state when the content you need appears after navigation. For long pages with lazy-loaded images, verify the resulting PDF: the consulted PDF documentation does not establish a universal procedure for triggering every site’s lazy loading.
Best Value
Troubleshooting PDF output
- The PDF looks unlike the browser page: Check whether print media is active by default. Emulate screen media if that is the intended appearance, and inspect the page’s print CSS.
- Colors or images are missing: Check whether background printing is enabled. For Puppeteer color fidelity, review
-webkit-print-color-adjustin the print CSS. - Content is cut off or breaks poorly: Review paper size, margins, scaling, and the page’s print and
@pagerules. Try CSS page-size preference where applicable. - Late content is absent: Wait for a page-specific selector or state that indicates the required content is present, then regenerate and inspect the PDF.
- No file appears: Confirm that a
pathwas passed and check the Node process’s working directory. Without a path, Playwright returns a buffer rather than saving a file. - Playwright PDF export is unavailable: Use Chromium; Playwright documents PDF generation as Chromium-only.
Or skip the browser setup
If you need an API rather than managing browser automation, ScreenshotNeo can return a PDF from one GET request. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.pdf
Use its PDF options for paper size, margins, landscape orientation, and page ranges. ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are not billed. It also provides an MCP server for AI agents. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots.
Sign up free for 1,000 screenshots a month, with no card required.
Frequently Asked Questions
Can Puppeteer or Playwright return the PDF without writing a file?
Yes. Both PDF methods return PDF data; Playwright returns a buffer. Provide a path to save a file, or handle the returned data in memory.
Can I use Playwright’s Firefox or WebKit browser to create this PDF?
No. Playwright documents PDF generation as Chromium-only.
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.




