Free tools Windows power users keep installed
One-click scans. No signup required.
Wait for Puppeteer’s network-idle condition before calling page.screenshot(). For most pages, use waitUntil: 'networkidle2' in page.goto(); use networkidle0 when you need the stricter condition of zero active connections. If you need a particular piece of content to appear, also wait for that element or application state explicitly—network idle is not a guarantee that every page has finished rendering.
Capture a screenshot after navigation reaches network idle
Install Puppeteer in your Node.js project if it is not already installed, then save this as an ES module file, such as screenshot.mjs. Replace the example URL with the page you want to capture.
As an Amazon Associate I earn from qualifying purchases.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle2',
});
await page.screenshot({path: 'page.png'});
} finally {
await browser.close();
}
Run it with node screenshot.mjs. The awaited page.goto() completes its chosen wait before the screenshot call runs. The official Puppeteer screenshot guide shows this pattern with networkidle2.
Choose networkidle0 or networkidle2
Both lifecycle options require the connection condition to hold for at least 500 milliseconds. The difference is the allowed number of active network connections:
#1 Best Overall
| Option | Network condition | When it fits |
|---|---|---|
networkidle0 |
No more than zero active connections for at least 500 ms. | Use when you want the stricter connection threshold and the page can become fully quiet. |
networkidle2 |
No more than two active connections for at least 500 ms. | Use when a page may maintain a small amount of background network activity and you do not need a zero-connection threshold. |
These are connection-count conditions, not measures of visual completeness. Neither is universally better: choose according to the page’s network behavior and the condition you need. See Puppeteer’s lifecycle event definitions.
Wait separately when navigation has already happened
If another step has already navigated the page, or you intentionally want to separate navigation from the idle wait, call page.waitForNetworkIdle() before capturing:
Rank #2
await page.goto('https://example.com');
await page.waitForNetworkIdle();
await page.screenshot({path: 'page.png'});
Its documented defaults are concurrency: 0 and idleTime: 500 milliseconds. The method always waits at least the configured idle time. You can set those options when a different connection threshold or idle interval suits your capture:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →await page.waitForNetworkIdle({
concurrency: 2,
idleTime: 1000,
});
Here, Puppeteer waits for at most two concurrent connections and an idle interval of at least 1,000 milliseconds. Consult the waitForNetworkIdle API reference for the installed Puppeteer version.
Wait for the content you actually need
A page can become network-idle before a delayed render, animation, or application-specific update is complete. Conversely, a page that keeps polling or streaming may not reach a strict idle condition even though the content you need is already visible. When readiness means “this element is present” or “this application state is ready,” wait for that condition explicitly, then take the screenshot.
await page.goto('https://example.com', {
waitUntil: 'networkidle2',
});
await page.waitForSelector('[data-testid="report-ready"]');
await page.screenshot({path: 'report.png'});
Replace the selector with one that represents the content on your page. Puppeteer’s navigation API reference documents page.goto() options and its return value: the promise resolves with the main-resource response, or with null in documented cases such as about:blank and same-URL hash navigation.
Rank #4
Choose screenshot output and page coverage
By default, page.screenshot() captures the viewport as PNG. The fullPage option defaults to false; enable it to capture beyond the visible viewport. The output format can be inferred from the filename extension, and a screenshot can also be returned as a Uint8Array or as a base64-encoded string. Options such as clip let you capture a specific region.
await page.screenshot({
path: 'full-page.png',
fullPage: true,
});
For a crop instead of a full-page capture, use a clip rectangle:
Best Value
- Used Book in Good Condition
await page.screenshot({
path: 'region.png',
clip: {x: 0, y: 0, width: 800, height: 600},
});
See Puppeteer’s Page.screenshot API reference for supported options and return behavior.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshoot waits that do not finish or capture too early
- Navigation appears to hang at network idle: the page may keep requests open or continually create new ones. Try
networkidle2instead ofnetworkidle0, or wait for the specific selector that indicates your required content is ready. - The screenshot misses content despite an idle wait: network inactivity does not establish that a delayed render or application update has completed. Add an explicit wait for the relevant selector or state before capturing.
- The screenshot only includes the visible viewport:
fullPagedefaults tofalse. SetfullPage: truewhen you want the entire page. - The navigation response is null: this is documented for cases including
about:blankand same-URL hash navigation. Do not assume every successful navigation supplies a main-resource response object. - The API behavior differs from an example: check the Puppeteer version installed in your project. The current documentation surfaced for this guide identifies version 25.12.0; verify the version-specific reference when exact behavior matters.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. Its GET endpoint returns an image or PDF from a URL. For example, this cURL request saves a WebP capture; see the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
ScreenshotNeo accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month—no card required.
Frequently Asked Questions
Does network idle guarantee that images and application content are ready?
No. It describes network connections over a time interval; wait for a relevant selector or application-specific state when that is what determines readiness.
Can page.goto() return null even if the call completes?
Yes. Puppeteer documents null responses for cases including navigating to about:blank or navigating to the same URL with only a hash 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.

