Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A blank Headless Chrome screenshot is a symptom, not a diagnosis. The capture may have finished before your application rendered, navigated to an error or redirect, used a viewport or clip that excludes the content, run in a different Headless implementation, or lacked graphics support required by WebGL or WebGPU. Diagnose those conditions in that order instead of adding random launch flags.

First inspect the final URL, navigation response, DOM, console and page errors. Then wait for an application-specific visible element, make the viewport and capture bounds explicit, compare browser modes only when the evidence points to a mode difference, and investigate GPU support only for GPU-dependent pages.

Start with this diagnostic sequence

  1. Confirm navigation: record the requested URL, final URL, main response status, Chrome version and Puppeteer version.
  2. Confirm content: inspect the DOM for the expected application root or a stable element that appears only after rendering.
  3. Wait for readiness: use a meaningful selector or predicate, preferably with a visibility check, rather than relying only on navigation completion.
  4. Check timing: determine whether delayed requests, timers or client-side rendering finish after your capture.
  5. Check geometry: set the viewport deliberately and review fullPage, clip and command-line window dimensions.
  6. Compare runtimes: if the same page differs between runs, record the binary and library versions and compare unified Headless, Headless Shell and headful Chrome.
  7. Investigate graphics: do this only when the page actually uses WebGL, WebGPU or another GPU-dependent path.

A screenshot file being created proves only that the capture operation completed. It does not prove that the intended document rendered.

Confirm the URL and main response before changing flags

Puppeteer’s page.goto() documentation describes the response returned for the main resource. Retain that response and log its status, then log page.url() after navigation. A redirect, login page, routing error or server error can produce a valid image that contains none of the page you expected.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Philips 24 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 241V8LB
  • CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
  • WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
  • A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents

Headless Shell has an important caveat: valid HTTP error statuses such as 404 or 500 do not necessarily make goto() throw. Treat the returned status as data you must inspect, not as an exception-only signal.

const response = await page.goto(url, { waitUntil: 'domcontentloaded' });
console.log({
  requestedUrl: url,
  finalUrl: page.url(),
  status: response ? response.status() : null,
});

Also attach diagnostics before navigation so failures are visible in CI logs:

page.on('console', message => {
  console.log('[console]', message.type(), message.text());
});
page.on('pageerror', error => {
  console.error('[pageerror]', error.message);
});
page.on('requestfailed', request => {
  console.error('[requestfailed]', request.url(), request.failure()?.errorText);
});

If the final URL or status is wrong, fix the target URL, authentication, routing or server response first. Increasing a timeout cannot repair navigation to the wrong document.

Verify that the DOM contains the finished application

Navigation milestones describe document loading, not necessarily application readiness. A client-rendered page can reach domcontentloaded while its meaningful content is still being fetched or mounted. Choose a selector tied to the state you need to capture: an application root with a ready attribute, a report title, a chart container, or another element that cannot exist until the relevant work is complete.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Puppeteer’s waitForSelector() documentation states that the default wait succeeds when the selector exists in the DOM. The { visible: true } option additionally requires that it is not hidden by display: none or visibility: hidden. Visibility is useful when a framework creates a placeholder node early, but the selector must still represent the content readers need.

await page.waitForSelector('#app[data-ready="true"]', {
  visible: true,
  timeout: 30_000,
});

If no readiness marker exists, wait for a stable element or an application-specific predicate:

Rank #2
Philips 22 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 221V8LB
  • CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
  • SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
await page.waitForFunction(() => {
  const chart = document.querySelector('.sales-chart');
  return chart && chart.querySelector('svg, canvas') && chart.getBoundingClientRect().height > 0;
}, { timeout: 30_000 });

Make a selector timeout actionable. Log the URL, a short HTML sample, console errors and failed requests when the condition does not arrive. A fixed sleep can help prove that timing is involved, but it is less precise and more flaky than waiting for a condition your application owns. Puppeteer’s page-interaction guidance covers waiting for stable, usable elements.

Handle delayed requests and timer-driven rendering

Pages may render content after API calls, animations, lazy loading or JavaScript timers. A navigation event can occur before those operations finish.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In Puppeteer, wait on the state you need

Use a targeted selector or waitForFunction predicate and catch its timeout so the missing condition is obvious. If the page exposes a loading indicator, wait for it to disappear only when its disappearance reliably means the requested content is complete. Avoid assuming one universal delay; page behavior varies by network, data and runtime.

On the Chrome command line, bound the capture wait

Chrome’s Headless command-line reference defines --timeout as the maximum wait, in milliseconds, before --screenshot, --dump-dom or --print-to-pdf captures content even if the page is still loading. It is a ceiling, not an application-readiness guarantee.

chrome --headless --screenshot --window-size=1280,900 --timeout=5000 https://example.com/

Increase the bound only after you have established that the page needs more time. If you control the script, a meaningful readiness condition is usually more deterministic than a large arbitrary delay.

Use virtual time for timer-dependent code

For pages whose behavior depends on JavaScript timers, test an appropriate --virtual-time-budget separately. Virtual time advances timer-driven code; it does not automatically prove that network requests, application state or visual assets are ready. Treat it as a diagnostic for time-dependent behavior, not as a universal blank-screenshot fix.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Dell 24 Monitor - SE2426H - 23.8-inch FHD (1920x1080) 144Hz 1ms Display, in-Plane Switching (IPS) Technology, AMD FreeSync™, TÜV 3-Star 2X HDMI, Tilt
  • Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
  • Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
  • Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
  • In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
  • Ultra-thin bezels: Maximize your viewing experience with thin bezels.

Make the viewport and capture bounds explicit

An empty image can be a geometry problem when the page is responsive, the screenshot is clipped, or the content lies outside the captured region. This is distinct from missing application content: inspect the DOM first, then inspect bounds.

Puppeteer settings to review

Set the viewport before navigation when layout depends on width, height, device scale or mobile emulation. In screenshot options, fullPage defaults to false; a clip rectangle can further constrain the output. The Puppeteer ScreenshotOptions reference documents these controls.

await page.setViewport({ width: 1280, height: 900, deviceScaleFactor: 1 });
await page.screenshot({
  path: 'screenshot.png',
  fullPage: true,
});

Temporarily remove clip to determine whether it is excluding the content. If the page is intentionally captured as one element or region, verify the element’s bounding box and that its width and height are non-zero.

Command-line dimensions

For CLI captures, use --window-size=width,height. The example below fixes the viewport while retaining a bounded wait:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
chrome --headless --screenshot --window-size=1280,900 --timeout=5000 https://example.com/

Changing dimensions cannot repair a failed request or an application that has not rendered. It only makes the tested capture area predictable.

Use a complete Puppeteer capture with diagnostics

This pattern checks the response, waits for a visible application state and captures the full page. Replace the URL, selector and timeout with values appropriate to your application.

Rank #4
Samsung 27" Essential S3 (S36GD) Series FHD 1800R Curved Computer Monitor
  • CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
  • SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
  • MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
  • KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
  • INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
import puppeteer from 'puppeteer';

const url = 'https://example.com/';
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();

page.on('console', message => {
  console.log('[console]', message.type(), message.text());
});
page.on('pageerror', error => {
  console.error('[pageerror]', error.message);
});
page.on('requestfailed', request => {
  console.error('[requestfailed]', request.url(), request.failure()?.errorText);
});

await page.setViewport({ width: 1280, height: 900, deviceScaleFactor: 1 });
const response = await page.goto(url, { waitUntil: 'domcontentloaded' });
console.log({ finalUrl: page.url(), status: response?.status() ?? null });

try {
  await page.waitForSelector('#app[data-ready="true"]', {
    visible: true,
    timeout: 30_000,
  });
} catch (error) {
  console.error('Readiness condition failed:', error.message);
  console.error('URL at failure:', page.url());
  throw error;
}

await page.screenshot({ path: 'screenshot.png', fullPage: true });
await browser.close();

If your page has no data-ready marker, substitute a stable selector or predicate. Do not copy the selector unchanged and assume it describes your application.

Check which Headless implementation and versions are running

Modern Headless Chrome shares the browser implementation with headful Chrome. Chrome documents the distinction in its Headless mode guide. Since Chrome 132.0.6793.0, the old Headless implementation is distributed as the separate chrome-headless-shell binary.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Current Puppeteer launch examples use headless: true for Headless Chrome and headless: 'shell' for Headless Shell. Compare modes only when your evidence suggests a mode-specific difference. Run the same URL, viewport, readiness condition and screenshot settings, and record the Chrome binary version and Puppeteer version for each run. A headful comparison is a controlled experiment, not a reason to permanently switch modes without understanding the difference.

Investigate GPU support only for GPU-dependent pages

Graphics configuration matters when the page uses WebGL, WebGPU or another rendering path that depends on GPU capabilities. It is not a general explanation for every blank HTML page.

Check the browser’s graphics feature status, such as chrome://gpu where available, and compare a supported configuration for the exact operating system, container and Chrome version. Chrome’s WebGPU, WebGL and Headless Chrome example shows an environment reporting software-only graphics with hardware acceleration unavailable and demonstrates specialized launch arguments for a GPU-oriented test.

Those arguments are workload-specific. Do not blindly enable unsafe features or disable the GPU for all screenshots. First establish that the page’s blank region is produced by a graphics-dependent component and that the same component works in a supported configuration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Sceptre New 22-Inch Gaming Monitor, FHD 1080p, Up to 144Hz, HDMI, DisplayPort, Built-in Speakers, Machine Black (E225W-FW144 Series, 2026)
  • 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
  • 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
  • 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Match the symptom to the appropriate fix

Observed clue Check Appropriate response
Wrong URL, error document or unexpected redirect Final URL and main response status Fix the target, authentication, routing or server response; inspect the returned response.
DOM exists but application content is absent from the image Application-specific selector and visibility Wait for the rendered state instead of relying only on navigation.
Content appears after a delay or timer Loading state, delayed requests and timer-driven code Wait on a meaningful condition; use CLI timeout or virtual time when appropriate.
Image is clipped, tiny or captures the wrong area Viewport, fullPage, clip and CLI window size Set dimensions deliberately and remove or correct unintended clipping.
Only one mode or binary differs Chrome version and Headless implementation Compare unified Headless, Headless Shell and headful runs with versions recorded.
Page specifically relies on WebGL or WebGPU Graphics feature status and runtime support Investigate GPU and runtime configuration for that workload; avoid applying special flags blindly.

Make captures reliable in CI

  • Log the evidence: requested URL, final URL, status, browser and Puppeteer versions, viewport, selector used and elapsed wait time.
  • Keep readiness application-specific: a selector that represents finished content is more stable than a universal sleep.
  • Preserve failure artifacts: when readiness times out, save the current URL, console output, page errors and, when practical, a diagnostic DOM dump.
  • Separate causes: test navigation, rendering readiness, geometry and graphics as independent hypotheses so a change has a clear reason.
  • Bound every wait: a timeout prevents a hung page from blocking a job, while the error identifies which condition failed.
  • Reproduce with versions: browser updates can change Headless behavior; record the exact binary and automation-library versions used by the failing job.

There is no documented universal percentage for blank screenshots or a single most-common cause. The correct fix depends on the evidence from your page and runtime.

Or skip the browser setup

ScreenshotNeo provides a website screenshot API and MCP server for developers. A GET request returns PNG, JPEG, WebP or PDF, so you can move capture out of your local Chrome setup when that is the practical choice.

For a direct 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.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}`);

Before capture, ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed as clean shots, and each response reports the result through X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The service also supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets plus custom viewports, retina scale, PDF paper and page-range controls, HTML/CSS-to-image, custom CSS and JavaScript, clicks before capture, selector or network-idle waits, request and resource blocking, custom headers, cookies, user agents and Authorization, timezone and geolocation, transparent backgrounds, resizing, TTL-based caching, signed 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 to ease 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

Every feature is available on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.

Frequently Asked Questions

Does --virtual-time-budget wait for network requests?

No. It advances JavaScript timer execution. You still need a readiness condition that proves the required requests and rendering work completed.

Should a headful comparison become the production fix?

Not automatically. Use it to isolate a mode-specific difference, then choose the supported Headless implementation that meets your deployment and rendering requirements.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What is the safest first change when the DOM is populated but the image is blank?

Inspect viewport, fullPage and clip after confirming the expected element is visible. Geometry changes address capture bounds; they do not substitute for application readiness.

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.