Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
browser automation

How to Use the waitUntil Option in Puppeteer and Playwright

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.

Use waitUntil in a navigation call to choose the browser lifecycle point at which that call may finish. Both Puppeteer and Playwright default to load, but their accepted values differ: Playwright supports commit, domcontentloaded, load and networkidle; Puppeteer supports domcontentloaded, load, networkidle0 and networkidle2. Choose the earliest boundary that lets your next operation work, then check the page’s actual content or state if that is what matters.

What waitUntil does

waitUntil tells a navigation method such as page.goto() how far the document’s loading lifecycle must progress before the navigation promise resolves. It is a boundary for navigation, not a general guarantee that an application has finished its own rendering, data fetching or background work.

In either library, the basic shape is:

await page.goto(url, { waitUntil: 'domcontentloaded' });

The value is passed in the navigation options. The examples below use JavaScript and the documented API names checked against the official references on September 29, 2026. Puppeteer’s references include both version 25.12.0 and a Next reference; check your installed package’s documentation when relying on version-sensitive details.

Which waitUntil value should you choose?

Value Framework What it waits for When it can fit
commit Playwright only The response has arrived and document loading has begun. When you need navigation to start but do not need the document parsed or its load event fired yet.
domcontentloaded Both The document’s DOMContentLoaded event. When the next step needs the parsed document but need not wait for every resource associated with the load event.
load Both; default in the cited references The page’s load event. When the next operation specifically depends on that lifecycle event.
networkidle Playwright only No network connections for at least 500 ms. Available as a lifecycle boundary, but Playwright discourages using it as a test-readiness signal.
networkidle0 Puppeteer only At most zero network connections for at least 500 ms. When you specifically want Puppeteer’s zero-connection idle condition.
networkidle2 Puppeteer only At most two network connections for at least 500 ms. When Puppeteer’s two-connection idle condition suits the page and task.

Use commit when only the start of navigation matters

Playwright’s commit boundary is earlier than document parsing: it means the response was received and the document started loading. It is useful when the caller needs that navigation to begin but has no immediate need to inspect parsed content. Puppeteer’s documented lifecycle type has no corresponding value, so do not copy this literal into Puppeteer code.

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

Use domcontentloaded for an earlier document boundary

DOMContentLoaded indicates that the document has been parsed. It can let a script proceed before waiting for all resources associated with the page’s load event. It does not establish that a single-page application has fetched and displayed the particular data your task needs.

Use load only when the load event is the requirement

load is the default in both cited references. That makes it a reasonable choice when your next operation truly depends on the load event, but it is not automatically the fastest or most meaningful choice for every page. Set the option explicitly when the intended boundary should be clear to future readers of the code.

Treat network idle as a specific condition, not “ready”

Playwright defines networkidle as no network connections for at least 500 ms and explicitly advises against using that method for tests. Puppeteer’s networkidle0 and networkidle2 are separate lifecycle names, each using a 500 ms idle period. An idle network does not prove that the UI displays the correct result; conversely, a page with ongoing requests may never satisfy an idle condition. For tests, assert the outcome that matters instead.

Playwright: navigation examples

Set the boundary in page.goto() options. This example uses domcontentloaded, then waits for a meaningful locator rather than assuming the lifecycle event means app-specific work is complete.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option
import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage();

try {
  const response = await page.goto('https://example.com', {
    waitUntil: 'domcontentloaded',
    timeout: 30_000,
  });

  // Navigation can complete with an HTTP error response. Check status if needed.
  console.log('HTTP status:', response?.status());

  // Wait for the outcome this task needs, not merely a lifecycle boundary.
  await page.getByRole('heading', { name: 'Example Domain' }).waitFor();
} finally {
  await browser.close();
}

The timeout above is an explicit example setting, not a claim about Playwright’s default. In the cited Page API, goto documents a default of 0 ms; navigation and default timeout configuration can affect the effective behavior. Check the documentation for your installed Playwright version before depending on a default.

Wait for a load state after another navigation action

Playwright’s waitForLoadState() waits for the requested state after navigation has been committed. The Page documentation says it is usually unnecessary because Playwright auto-waits before actions. Prefer a locator or web-first assertion for a condition your test actually needs. If you do use a load state, apply it to the page that navigated:

await page.getByRole('link', { name: 'Products' }).click();
await page.waitForLoadState('domcontentloaded');
await page.getByRole('heading', { name: 'Products' }).waitFor();

Puppeteer: navigation examples

Puppeteer uses the same navigation-options shape for its supported lifecycle names. Its WaitForOptions reference also accepts an array of lifecycle events: all listed events must fire before the wait resolves.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();

try {
  const response = await page.goto('https://example.com', {
    waitUntil: ['domcontentloaded', 'networkidle2'],
    timeout: 30_000,
  });

  console.log('HTTP status:', response?.status());
  await page.waitForSelector('h1');
} finally {
  await browser.close();
}

The array means “wait for both listed lifecycle events,” not “accept whichever happens first.” If you only need parsed markup, using domcontentloaded alone avoids making completion depend on the idle condition as well.

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

The cited Puppeteer Next WaitForOptions reference documents a 30,000 ms timeout default and says timeout: 0 disables the timeout. Defaults are version-sensitive; the explicit 30-second setting in the example makes its intent clear without relying on that default.

Navigation caused by a click

In Puppeteer, register the navigation wait before clicking. Starting the wait after the action risks missing a navigation that has already begun.

const [response] = await Promise.all([
  page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
  page.click('a.my-link'),
]);

console.log('Navigation response:', response?.status() ?? 'no response');

Puppeteer counts History API URL changes as navigation. An anchor navigation or History API navigation can resolve with a null response, so code should not assume that waitForNavigation() always returns an HTTP response.

Differences to remember when switching frameworks

  • Network-idle spelling: Playwright uses networkidle; Puppeteer uses networkidle0 and networkidle2.
  • Earliest documented boundary: Playwright has commit; the cited Puppeteer lifecycle type does not.
  • Multiple conditions: Puppeteer’s cited WaitForOptions accepts an array and requires every listed event; the cited Playwright navigation option uses one waitUntil value.
  • Timeout documentation: the cited Playwright goto reference documents a 0 ms default, while Puppeteer’s cited Next options reference documents 30,000 ms. These are framework- and reference-version-specific settings, not universal browser defaults.

Troubleshooting waitUntil problems

The navigation never reaches network idle

A continuing request can prevent the idle condition from occurring, and an idle condition may be unnecessary for the task. Choose an earlier boundary if the next step permits it, or wait for a specific locator or application condition. Do not use network quiet as a substitute for verifying rendered data.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • 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

The option is rejected or behaves differently after a framework switch

Check the accepted literals for the library and installed version. In particular, do not use Playwright’s commit or networkidle names in Puppeteer, or Puppeteer’s networkidle0/networkidle2 names in Playwright.

The page reaches the selected event but the expected content is missing

The event only marks a navigation lifecycle boundary. Add a wait for a selector, locator or other observable state that represents the content your script needs. If the page returns a valid HTTP error status such as 404 or 500, Playwright’s goto() does not throw solely for that status; inspect the returned response status when it matters.

A click-triggered navigation wait times out

For Puppeteer, make sure waitForNavigation() is armed before the click, preferably together in Promise.all. Also check whether the click changes the page through a History API route and therefore produces a navigation without a conventional response.

The error is a timeout or navigation failure

Check the framework’s configured navigation or default timeout and the installed version’s documentation. Playwright documents failures for cases such as an invalid URL, navigation timeout, unreachable server, SSL failure or main-resource failure. A valid HTTP 404 or 500 response is different: inspect its status rather than treating it as a thrown navigation failure.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is to obtain a website screenshot rather than control an automated browser navigation, ScreenshotNeo provides a screenshot API. Its request does not expose Puppeteer or Playwright’s waitUntil option, so use browser automation when that lifecycle control is required.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. Cookie and consent banners are accepted or removed before capture, along with supported newsletter popups and chat widgets; 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. An MCP server provides screenshot tools for AI agents, and 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

Does waitUntil wait for JavaScript frameworks to finish rendering?

No. It waits for a navigation lifecycle boundary. Wait separately for the UI state your script needs.

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

Can I use networkidle as a screenshot readiness guarantee?

No. It describes network activity, not whether the image or content you expect has rendered.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.