Recommended Free Tools
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use Puppeteer when you need Node.js to render a live webpage or supplied HTML in a browser and save the result as a PDF. For a webpage, navigate to its URL; for HTML, load that markup into a page first. Puppeteer’s page.pdf() uses print CSS by default and returns PDF bytes, which you can save to a file or send elsewhere. This guide covers both inputs, print layout, output handling, and common failure points.
Choose the right input workflow
There are two related jobs: rendering a webpage that is already available at a URL, and rendering HTML content your application already has. Both ultimately use a browser page and Puppeteer’s PDF method, but the page-loading step differs.
- Use a URL when the page is hosted and should render with its own scripts, stylesheets, images, and browser behavior.
- Use HTML content when your app generates the markup, such as an invoice or report. The markup must be loaded into a browser page before PDF generation; its referenced CSS, fonts, and images must also be reachable if they are external.
Puppeteer is a concrete browser-automation route, not a claim that it is universally faster or better than alternatives. Playwright also documents PDF generation. Both APIs use print CSS media by default; Puppeteer’s PDF guide additionally says font loading is awaited by default. See the Puppeteer PDF generation guide.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsInstall Puppeteer and convert a webpage URL
In a Node.js project, install Puppeteer:
npm install puppeteer
Save this as webpage-to-pdf.mjs and run it with node webpage-to-pdf.mjs:
#1 Best Overall
import puppeteer from 'puppeteer';
const url = process.argv[2] ?? 'https://example.com';
const outputPath = process.argv[3] ?? 'page.pdf';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle2' });
await page.pdf({
path: outputPath,
format: 'A4',
printBackground: true,
});
console.log(`Saved PDF to ${outputPath}`);
} finally {
await browser.close();
}
For example, node webpage-to-pdf.mjs https://example.com example.pdf navigates to the supplied URL and writes the file. The official guide illustrates launching a browser, navigating with waitUntil: 'networkidle2', setting a path, and closing the browser. That wait condition is an example, not a guarantee that every site is ready when network activity becomes idle. Pages that load content after an API call, user interaction, or application-specific signal may need an explicit readiness check.
What each operation does
puppeteer.launch()starts a browser instance controlled by Puppeteer.browser.newPage()creates the tab used for rendering.page.goto(url, options)navigates to the live page and waits according to the chosen readiness condition.page.pdf(options)renders the page as a PDF. Withpathset, Puppeteer writes the output file.- The
finallyblock closes the browser whether the operation succeeds or throws, preventing a failed navigation or write from skipping cleanup.
Convert HTML content rather than a URL
HTML still needs to be rendered in a browser page before calling page.pdf(). Puppeteer’s API reference documents page content operations; consult the current Page.pdf() reference and the page API for the exact content-loading method supported by your installed version. The general sequence is: create a page, load your HTML into it using that version’s documented content API, wait for any required assets or application work, then call page.pdf().
For self-contained HTML, inline the CSS and data where practical. If the HTML references relative paths, make sure the browser has a meaningful base URL or use absolute URLs; otherwise stylesheets, images, and fonts can fail to load. If the markup includes remote assets, network readiness alone may not mean those assets have rendered correctly. Verify the resulting PDF rather than assuming the HTML string guarantees a complete document.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Rank #2
Control print styling, page size, and output
Puppeteer generates PDFs with the print CSS media type by default. This means print-specific rules such as @media print apply, and screen-only styling may not appear as expected. To render with screen styling instead, call page.emulateMediaType('screen') before page.pdf(). The equivalent Playwright API uses page.emulateMedia() before PDF generation; see the Playwright Page API.
Useful PDF options
| Need | Approach |
|---|---|
| Save directly to disk | Set Puppeteer’s path option, for example path: 'report.pdf'. |
| Return bytes to application code | Call page.pdf() without relying on a file path; the API returns a Uint8Array. |
| Set a page format or dimensions | Use the documented PDF options such as format, or set width and height as appropriate. Check current option details in the Puppeteer PDFOptions reference. |
Use CSS @page dimensions as the authority |
Set preferCSSPageSize: true; Puppeteer documents that CSS page size then takes priority over width, height, or format settings. |
| Add a footer | Use footerTemplate with the PDF display-header/footer options described in the PDF options reference. |
| Retain background colors and graphics | Enable printBackground. Print rendering may still alter colors unless the CSS requests exact color adjustment. |
Browsers modify colors for printing by default. If exact colors matter, Puppeteer points to the CSS property -webkit-print-color-adjust; for example, a print stylesheet can use * { -webkit-print-color-adjust: exact; }. Test this against the browser and document design you deploy, since print styles affect the final appearance.
Return the PDF from a Node.js endpoint
Because page.pdf() returns a Uint8Array, you can pass its bytes to an HTTP response rather than writing a permanent file. The essential pattern is to generate the PDF, set a PDF content type, and send the bytes. In a web server, still close the browser in a finally block, and ensure a response is not sent twice if navigation or rendering throws.
Rank #3
For a recurring service, decide deliberately whether a browser is launched per request or managed by a longer-lived worker. Browser lifecycle, concurrency limits, memory, process isolation, and deployment packaging depend on the hosting environment; the cited API documentation does not establish one universal production or serverless recipe. Validate the browser installation and resource limits in the actual runtime before relying on a deployment pattern.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Wait for the right page state
A PDF can be technically generated yet incomplete if the page was captured before its content was ready. The official Puppeteer guide uses networkidle2 as an example navigation wait. It is useful for pages that settle, but not a substitute for knowing how the target application signals completion.
- For a static page, a navigation completion condition may be sufficient.
- For a client-rendered report, wait for a known element or application-ready state before printing.
- For pages with web fonts, Puppeteer’s PDF guide states that PDF generation waits for fonts by default; confirm that the intended font actually loaded rather than silently falling back.
- For long pages, test page breaks and print-specific CSS. Screen layout does not always translate into the desired paper layout.
Troubleshooting common PDF problems
The PDF is blank or missing dynamic content
The page may have been printed before client-side rendering completed, or the target URL may redirect to an error, login, or bot-check page. Wait for an application-specific selector or ready signal, inspect the loaded page, and verify that the URL is accessible in the browser session Puppeteer created.
Rank #4
Styles, images, or fonts are missing
Check browser console and network failures, relative asset paths, access controls, and whether remote resources are reachable from the runtime. For HTML strings, external relative URLs may resolve differently than they do on the site where the markup originated. Use absolute URLs or provide an appropriate base context.
Colors or backgrounds differ from the screen
PDF generation uses print media by default, so inspect @media print rules and enable background printing if needed. If color fidelity is important, apply -webkit-print-color-adjust in print CSS and verify the saved PDF in a PDF viewer.
The output ignores CSS page size
When the stylesheet’s @page size should control paper dimensions, set preferCSSPageSize: true. Avoid conflicting explicit dimensions unless you intend the PDF option values to take precedence.
Browser processes remain after an error
Put browser.close() in a finally block, as in the URL example. This ensures cleanup after navigation, PDF generation, or file-writing failures.
Or skip the browser setup
If you need a screenshot of a webpage rather than a locally controlled PDF layout, ScreenshotNeo offers a one-request API. It is a website screenshot API and MCP server, not a replacement for every PDF workflow; its API can return a PDF as well as PNG, JPEG, or WebP. See the ScreenshotNeo website and API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Replace YOUR_API_KEY with your key and change the target URL. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are not billed. An MCP server lets AI agents use screenshot tools, and the Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. For PDF output, set the documented format option rather than saving the response with a misleading image extension. Sign up for ScreenshotNeo free: 1,000 screenshots a month, no card required.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteSources and scope
The method details above are based on the official Puppeteer Page.pdf() method, PDF generation guide, and PDFOptions interface, plus Microsoft’s Playwright Page API. These sources document API behavior, not comparative speed, performance benchmarks, or a universal deployment configuration.
Frequently Asked Questions
Can I use Playwright instead of Puppeteer for PDF generation?
Yes. Playwright documents `page.pdf()` and its print-media default. Its media-emulation method is `page.emulateMedia()`, rather than Puppeteer’s `page.emulateMediaType()`.
Does Puppeteer return PDF data or only save a file?
Its PDF method returns a `Uint8Array`; you can also provide a `path` option to write the output to a file.
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.
Free tools Windows power users keep installed
One-click scans. No signup required.

