Recommended Free Tools
A blank Puppeteer PDF usually means the page was empty when printing, the page was ready on screen but hidden by print CSS, or PDF settings excluded the content. Diagnose those stages in order: prove the DOM contains the expected data, compare screen and print media, verify fonts and resources, then reduce PDF options to known defaults. The following workflow works for both page.goto() and page.setContent() jobs.
Why is my Puppeteer PDF blank?
Puppeteer separates three things that are easy to conflate:
- Page creation: Node.js navigates to a URL or injects HTML.
- Application readiness: client-side JavaScript fetches data, inserts elements, and loads styles, images, and fonts.
- Print rendering:
page.pdf()lays out the page with print CSS and your paper, range, scale, margin, and background settings.
A successful navigation or a resolved setContent() promise does not prove that an application has finished rendering. Conversely, a page that looks correct in a browser can disappear in print because an @media print rule sets a container to display:none, hides overflow, changes colors, or moves content outside the printable area.
1. Establish whether the page itself contains content
Do this before changing launch flags. Inspect the title, serialized HTML, a selector that must exist in a valid document, visible text, and a screenshot. If these checks fail, PDF generation is not the root problem.
#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
Use an application-ready condition
For a URL, choose a navigation lifecycle condition that fits the site and then wait for the application’s own signal. For injected HTML, await setContent() and wait for a selector or an explicit readiness flag. networkidle2 is useful in many examples, but network idleness alone cannot tell you that a client-rendered table or chart has finished.
Minimal diagnostic program
import puppeteer from 'puppeteer';
const html = `<!doctype html>
<html><body>
<main id="pdf-content"><h1>Invoice 123</h1></main>
</body></html>`;
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
page.on('console', msg =>
console.log('PAGE:', msg.type(), msg.text()));
page.on('pageerror', error =>
console.error('PAGE ERROR:', error));
page.on('requestfailed', request =>
console.error('REQUEST FAILED:', request.url(), request.failure()?.errorText));
page.on('response', response => {
if (response.status() >= 400)
console.error('HTTP', response.status(), response.url());
});
await page.setContent(html, { waitUntil: 'networkidle0' });
await page.waitForSelector('#pdf-content'); // Replace with your real ready condition.
console.log('Title:', await page.title());
console.log('HTML length:', (await page.content()).length);
console.log('Text:', await page.$eval('#pdf-content', el => el.innerText));
await page.screenshot({ path: 'before-print.png', fullPage: true });
await page.pdf({
path: 'output.pdf',
printBackground: true,
waitForFonts: true
});
} finally {
await browser.close();
}
The screenshot is decisive: if before-print.png is blank, fix navigation, data, JavaScript, or resource loading first. If it is populated but the PDF is blank, continue with print-media and PDF-option checks.
2. Compare screen and print rendering
Puppeteer documents that page.pdf() generates a PDF with the print CSS media type. Temporarily switch to screen media and produce a diagnostic PDF:
await page.emulateMediaType('screen');
await page.pdf({ path: 'screen-media.pdf', printBackground: true });
If this file contains the expected content while the normal PDF does not, inspect every print rule. Search for display:none, visibility:hidden, transparent text, zero dimensions, restrictive height/overflow, absolute positioning, print-only page breaks, and selectors that hide the application root. The media comparison identifies a print-CSS difference; it is not a universal cure. Repair the rule or deliberately use screen media when that is the intended output.
Check computed visibility when needed
const state = await page.$eval('#pdf-content', el => {
const s = getComputedStyle(el);
const r = el.getBoundingClientRect();
return {
display: s.display,
visibility: s.visibility,
opacity: s.opacity,
width: r.width,
height: r.height,
text: el.innerText
};
});
console.log(state);
3. Wait for data, images, styles, and fonts
Navigation and injected HTML
For a navigated page, use an appropriate waitUntil value and then wait for the application’s ready selector:
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
await page.goto('https://example.com/report', { waitUntil: 'networkidle2' });
await page.waitForSelector('#report-ready');
For generated markup, await the content assignment itself:
await page.setContent(html, { waitUntil: 'networkidle0' });
await page.waitForSelector('#pdf-content');
Prefer a real condition such as a completed status attribute, a known row count, or a window flag over an arbitrary timeout. If you control the app, set window.__PDF_READY__ = true after data and layout are complete, then wait with page.waitForFunction(() => window.__PDF_READY__ === true).
Fonts and externally loaded resources
The current PDF reference waits for fonts by default (waitForFonts: true). Keep that default unless you have identified a specific font-loading hang. Turning it off can shorten a wait while producing substituted or missing fonts. In a background page, font waiting may require bringing the page to the front:
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsawait page.bringToFront();
await page.pdf({ path: 'output.pdf', waitForFonts: true });
Log failed requests and HTTP errors. A stylesheet that returns an error, an image blocked by authentication, or a script exception can leave an otherwise valid shell empty.
4. Audit PDF options against documented defaults
Start with a minimal call, then add options one at a time. The documented defaults are letter paper, scale 1, zero margins, omitBackground: false, printBackground: false, preferCSSPageSize: false, and an empty pageRanges value meaning all pages.
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
| Option | How it can make output appear blank | Diagnostic action |
|---|---|---|
pageRanges |
A range outside the document emits no useful pages. | Remove it or use the default empty value. |
format, width, height |
An incompatible or tiny paper box can clip content. | Try format: 'Letter', then compare explicit dimensions. |
scale |
An extreme value can shrink content beyond practical visibility. | Return to scale: 1. |
margin |
Large margins can consume the printable area. | Use zero or modest margins while diagnosing. |
printBackground |
Background graphics and fills are omitted when false. | Set true if visible design depends on backgrounds; this does not remove ordinary foreground text. |
omitBackground |
Can make a design that relies on a colored page look white. | Leave it false while comparing output. |
preferCSSPageSize |
CSS @page dimensions can override the paper you expected. |
Toggle it and inspect your @page rules. |
await page.pdf({
path: 'known-good.pdf',
format: 'Letter',
scale: 1,
margin: { top: '0', right: '0', bottom: '0', left: '0' },
printBackground: true,
omitBackground: false,
preferCSSPageSize: false,
waitForFonts: true
});
Once this baseline works, reintroduce page ranges, custom dimensions, margins, and CSS-page-size precedence individually.
5. Separate Node.js, page, and browser failures
Page-side failures
page.on('console') reveals browser console messages; page.on('pageerror') captures uncaught page exceptions. A failed API call or a JavaScript exception may prevent the component that supplies all printable content from mounting.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Browser-process failures
Run headful for a visual inspection:
const browser = await puppeteer.launch({ headless: false });
When startup, sandboxing, crashes, or missing libraries are suspected, use dumpio: true to forward browser process logs:
const browser = await puppeteer.launch({ dumpio: true });
Verbose protocol and browser logs can contain sensitive URLs, headers, or document data. Enable them only in a controlled debugging environment.
Always clean up
Keep browser.close() in a finally block. Leaked browser processes can exhaust memory and make later jobs fail in ways that resemble rendering bugs.
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
6. Check the Puppeteer and browser installation
Puppeteer’s supported-browser table maps package versions to browser versions. Confirm that the package installed in deployment and the executable it launches are a supported pair. Puppeteer v20 and later downloads Chrome for Testing as part of its normal installation model; a production image that skips that download may have no usable browser.
- Print the installed Puppeteer version from the deployment lockfile or package manager.
- Verify the browser executable exists in the running image and has its required shared libraries.
- Compare local and hosted launch arguments only after logs show a runtime or sandbox error.
- If local works but a hosted job does not, inspect CPU allocation, memory, temporary storage, and browser startup logs. Deployment-specific configuration matters only when the environment differs or the logs point to it.
Do not add a launch flag merely because it appears in an internet snippet. A flag is a fix only when the observed error identifies the condition it changes.
Common symptoms and targeted fixes
| Symptom | Likely boundary | Fix |
|---|---|---|
| Screenshot before PDF is blank | Navigation, data, script, or resource failure | Inspect title, HTML, selector, console, page errors, failed requests, and HTTP responses. |
| Screenshot has content; PDF is blank | Print CSS or PDF geometry | Compare emulateMediaType('screen'), inspect print rules, then reset options. |
| Only colors or images disappear | Background printing | Use printBackground: true and verify resource responses. |
| Only some pages disappear | Range or page-break configuration | Clear pageRanges, inspect @page, dimensions, and margins. |
| Text is missing or substituted | Font readiness or blocked font files | Check font requests; keep waitForFonts: true unless a diagnosed issue requires otherwise. |
| Works locally, fails in deployment | Browser/runtime mismatch or resource limits | Verify supported versions, executable installation, libraries, CPU, memory, and browser logs. |
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server when you need an image or PDF from a URL without maintaining Puppeteer and a browser runtime. It accepts cookie and consent banners as a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
One-call cURL example
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo documentation for output and request options. It supports full-page captures with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets and custom viewports, retina scale, PDF paper size/margins/landscape/page ranges, HTML or CSS to image, custom JavaScript and CSS, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, easing migration.
| Plan | Included shots | Price |
|---|---|---|
| Free | 1,000 per month | $0, no card |
| Starter | 3,000 | $5 |
| Growth | 15,000 | $15 |
| Pro | 60,000 | $39 |
| Scale | 250,000 | $99 |
| Business | 1,000,000 | $249 |
Yearly billing gives two months free, and every feature is available on every plan. Create a free ScreenshotNeo account for 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Performance, reliability, and cost notes
- Waiting for a real ready signal avoids both premature blank PDFs and wasteful long sleeps.
- Reuse a browser process for batches, but create and close pages per job so state, cookies, and listeners do not leak.
- Capture diagnostics only while troubleshooting; screenshots and verbose logs add I/O and may expose document data.
- Cache immutable assets or use a controlled browser cache when appropriate, but do not let stale application data masquerade as a successful render.
- Keep the PDF configuration deterministic: fixed viewport, timezone, locale, fonts, paper size, and margins reduce environment-dependent differences.
FAQ
Does networkidle2 guarantee that a PDF is ready?
No. It describes network activity, not whether your application has inserted its final data or completed layout. Wait for an application-specific selector or readiness condition.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Should I always set printBackground: true?
Only when the document’s intended appearance depends on background fills or images. It does not repair missing foreground content or print CSS that hides the content.
Can changing headless mode fix a blank PDF?
Headful mode is a diagnostic aid that lets you see the page. It is not a general PDF fix; use it to identify the failing stage, then correct that stage.
Frequently Asked Questions
Why does the PDF have pages but no visible text?
Check print-media rules, computed visibility, text color, scale, margins, and whether the selected page range actually contains the content.
What is the safest first change when debugging?
Remove custom PDF options, verify a populated pre-print screenshot, and add options back one at a time.
Why do fonts cause intermittent output differences?
Font files may be delayed or blocked. Confirm their requests and retain Puppeteer’s default font wait unless a measured loading problem requires a change.
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.

