Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
browser automation

Does Puppeteer’s page.goto() waitUntil Wait for WebSockets?

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

No—not as a guarantee that a WebSocket is ready. Puppeteer’s page.goto() waits for a navigation lifecycle condition. Even networkidle0 and networkidle2 describe network quiet, not whether a WebSocket connected, stayed open, or delivered the application data your script needs. After navigation, wait for a page-specific signal or state tied to that data.

What page.goto() waits for

page.goto(url, { waitUntil }) navigates to a URL and resolves according to the selected Puppeteer lifecycle event. The documented choices are load, domcontentloaded, networkidle0, and networkidle2. These conditions answer questions about the document’s navigation and network activity; they are not a general-purpose application-readiness check.

The current Puppeteer API pages reviewed for this article displayed version 25.12.0 on September 29, 2026. The lifecycle type reference is under Puppeteer’s /next/ documentation, so check the API for the version installed in your project if exact compatibility matters. The documentation does not establish that an open WebSocket is counted the same way by every supported browser and protocol backend. It is therefore too broad to claim either that a persistent socket always blocks networkidle0 or that it is always ignored.

What each waitUntil condition tells you

Condition Documented meaning What it does not prove
domcontentloaded The document’s DOM content-loaded lifecycle event occurred. That the page has finished all later work, opened a useful socket, or received the data your task requires.
load The document’s load lifecycle event occurred. That application data delivered after navigation is ready, including data expected over a WebSocket.
networkidle0 No more than zero network connections for at least 500 ms. That a WebSocket handshake completed, that a connection remains usable, or that a particular message arrived.
networkidle2 No more than two network connections for at least 500 ms. That any remaining activity is harmless, or that the page’s application state is ready.

The 500 ms is a documented quiet-period threshold, not a guarantee that the application has completed its work. A page can be network-quiet before the relevant data arrives, and unrelated requests can keep activity going even when the data you need is already available. The official API references do not settle how open WebSockets affect the idle accounting in every browser/protocol combination, so treat the lifecycle condition as a signal about network activity, not a test of socket readiness.

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

Choose a wait condition that matches the task

Use a document lifecycle event for document readiness

If the next step only needs the page’s document to be parsed, domcontentloaded can be an appropriate navigation boundary. If it depends on resources associated with the document’s load lifecycle, use load. Neither should be interpreted as evidence that live data has arrived.

Use network idle only when network quiet is what you need

networkidle0 and networkidle2 can be useful when the task genuinely depends on a period of relative network quiet. They are generic thresholds, however. They may wait on activity unrelated to your goal, and they do not identify which requests matter. Do not choose one simply because the page uses WebSockets.

Use application readiness when data readiness is what you need

If your script needs a socket-fed value, define readiness in terms of the application: for example, a known status element appearing, a required value becoming available, or an application-owned flag changing after the relevant message is processed. The right predicate depends on the site and the task. A socket being open by itself may still be insufficient if the subscription or data update has not completed.

Wait for a page-specific signal after navigation

One practical pattern is to navigate at a document lifecycle boundary, then wait for a condition that the application sets only after it has processed the data you need. In the example below, window.__APP_DATA_READY__ is an illustrative application-owned flag, not a built-in Puppeteer property. Your page or test fixture must set it at the correct point; replace it with a real selector or predicate that represents your task.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const puppeteer = require('puppeteer');

async function main() {
  const url = process.argv[2];
  if (!url) {
    throw new Error('Usage: node capture.js https://example.com');
  }

  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.goto(url, {
      waitUntil: 'domcontentloaded',
      timeout: 30000,
    });

    // This flag must be set by the application after the required
    // WebSocket-fed data has been received and processed.
    await page.waitForFunction(
      () => window.__APP_DATA_READY__ === true,
      { timeout: 15000 },
    );

    const result = await page.evaluate(() => ({
      ready: window.__APP_DATA_READY__,
      text: document.querySelector('[data-result]')?.textContent ?? null,
    }));
    process.stdout.write(`${JSON.stringify(result)}n`);
  } finally {
    await browser.close();
  }
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Run it with node capture.js https://your-site.example after installing Puppeteer in the project. The URL is an example; use a page where your chosen readiness signal is actually defined. The example waits for data readiness, not merely for an open socket. If you cannot change the page to expose a flag, use an observable state already present in the UI or application, such as a selector or text value that appears only when the required data is rendered. Avoid waiting for an arbitrary fixed delay unless there is no better signal: a delay can be too short on a slow run and unnecessarily long on a fast one.

Keep navigation waits distinct from WebSocket waits

page.waitForNavigation() is navigation-oriented too: Puppeteer documents it as waiting for a new URL or reload, and History API URL changes count as navigation. That can help synchronize code around a navigation event, but it does not establish that a WebSocket message arrived or that the page processed it. A URL change and application-data readiness are separate conditions unless the application explicitly makes them the same event.

Puppeteer also provides page.waitForNetworkIdle() as a separate page method. Its documented options use a default concurrency of 0 and idleTime of 500 ms; it always waits at least the configured idle time. This remains a network-idle wait, not a WebSocket-specific readiness method. If exact option behavior matters to your installed release, consult that release’s API reference.

Troubleshoot waits that time out or finish too early

  • The navigation wait times out: The selected lifecycle condition may not occur within the timeout, perhaps because the page continues making requests. Try a lifecycle boundary appropriate to the task, such as domcontentloaded, then wait separately for the specific state you need. Do not increase the timeout as a substitute for identifying the desired condition.
  • networkidle0 appears stuck: The page may have ongoing network activity. The documentation reviewed does not specify how every browser/protocol backend accounts for a persistent WebSocket, so do not infer from this symptom that all WebSockets necessarily block the condition. If your task needs application data rather than global quiet, switch to an application-specific predicate.
  • networkidle2 resolves but the expected value is missing: Its threshold permits up to two network connections during the quiet-period condition. More fundamentally, a network-idle condition does not establish that a particular application message was received. Add a wait for the relevant rendered value or application state.
  • The custom readiness wait times out: Confirm that the page really exposes the selector, flag, or state used by the predicate and that it becomes true only after the relevant data is processed. A misspelled selector, an unset test flag, or a page that never reaches the expected state can all make the condition unsuitable. Log or inspect the actual UI state before changing the timeout.
  • The wait succeeds intermittently: A condition may be observing an intermediate state, or the application may update asynchronously. Tie the predicate to the final value or state needed by the next action, rather than to a transient indication that a connection exists.
  • A History API route change is mistaken for data readiness: Navigation synchronization can observe URL changes, including History API changes, but that does not prove the associated screen has received its live data. Add a second, application-specific wait for the required state.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance and reliability trade-offs

Waiting for a broad network-quiet condition can make a script slower when irrelevant activity continues; choosing a short document lifecycle boundary and then checking the needed state can avoid waiting for unrelated work. Conversely, a predicate that is too narrow or tied to an unstable UI detail can produce flaky automation. Select a condition that is both observable and meaningful to the next operation.

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

There is no universal timeout value established by the cited API references for WebSocket readiness. The 500 ms value belongs to the network-idle definition and should not be repurposed as a general socket or data timeout. Set navigation and application-state timeouts according to the page and task, report which wait failed, and preserve enough error context to distinguish a navigation problem from missing application data. The code’s separate 30-second navigation and 15-second readiness limits are example choices, not Puppeteer defaults or performance recommendations.

Or skip the browser setup

If your goal is a screenshot rather than inspecting WebSocket state or extracting live application data, ScreenshotNeo can return an image or PDF through a single API request. Its capture flow accepts cookie or consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status in headers. It also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

For the API key and request options, see the ScreenshotNeo documentation.

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

This captures a page; it does not replace waiting for a WebSocket-fed application value when your code needs that value. Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

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

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 *

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.

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

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.