October 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 PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

Puppeteer Page Events: How to Listen for Page Changes

Use Puppeteer Page event listeners to track lifecycle changes, frame navigation, popups, JavaScript errors, and network activity without common race conditions.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Listen for changes on a Puppeteer page with page.on('eventName', handler). Use page.once() for a one-time callback and page.off() with the same callback function to remove a listener. The examples below cover lifecycle events, URL changes, popups, page errors, and network requests—and explain how to avoid navigation races.

Register and remove a Page event listener

A Puppeteer Page is an EventEmitter. Register a persistent listener with page.on(eventName, handler); register one that runs only once with page.once(eventName, handler). To remove a persistent listener, pass the same function reference to page.off().

As an Amazon Associate I earn from qualifying purchases.

function logRequest(request) {
  console.log('A request was made:', request.url());
}

page.on('request', logRequest);

// Later, when the listener is no longer needed:
page.off('request', logRequest);

// Run a callback only for the next load event:
page.once('load', () => console.log('Page loaded!'));

For a callback you may need to remove later, use a named function or save the function in a variable. An inline arrow function passed directly to page.on() is difficult to remove unless you kept a reference to it.

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

Choose an event for the change you need

What you need to detect Event or API What the handler receives or inspects
The document reaches its load milestone load Page lifecycle event
The document’s DOM is ready domcontentloaded Page lifecycle event
A frame navigates, attaches, or detaches framenavigated, frameattached, framedetached A Frame
The page opens a popup popup The popup’s Page
Page JavaScript logs a message console A ConsoleMessage
Page JavaScript throws an uncaught exception pageerror Error data
Observe network activity request, response, requestfinished, requestfailed An HTTPRequest or HTTPResponse

framenavigated is useful for detecting URL changes, but it can report navigation in a frame rather than only in the main document. Inspect the supplied frame if you only care about the top-level page. Puppeteer dispatches frame lifecycle events on the parent page.

Listen for lifecycle events and URL changes

load and domcontentloaded mark different document lifecycle milestones. To observe a frame URL change, listen for framenavigated and inspect the frame URL:

page.on('framenavigated', frame => {
  console.log('Frame navigated:', frame.url());
});

page.once('domcontentloaded', () => {
  console.log('The DOM content is ready');
});

The frame event may concern an iframe. If your logic is specifically about the main frame, compare the event’s frame with page.mainFrame() before acting.

Wait for an event without racing navigation

If a click or other action is expected to cause navigation, start waiting for the event and trigger the action together. Waiting only after the action can miss an event that has already fired.

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
const [response] = await Promise.all([
  page.waitForNavigation(),
  page.click('a.next-page'),
]);

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

Use the event that matches what the action is expected to do. A popup is not the same as navigation in the current page, and a single-page application may update content or history without producing a full document navigation.

Handle popups, console messages, and page errors

Capture a popup

The page’s popup event supplies the new tab or window as a Puppeteer Page. It is associated with the parent page’s browser context.

page.once('popup', async popup => {
  await popup.waitForLoadState?.('load');
  console.log('Popup URL:', popup.url());
});

await page.click('a[target="_blank"]');

Puppeteer wait APIs vary by version. If your installed version does not provide the method shown, use its documented page lifecycle wait method or inspect the popup after the event; check the API reference matching your installed release.

Inspect browser-side diagnostics

page.on('console', message => {
  console.log('Page console:', message.type(), message.text());
});

page.on('pageerror', error => {
  console.error('Uncaught page error:', error);
});

A console event is a Puppeteer ConsoleMessage, not the Node.js console itself. The pageerror event is for uncaught exceptions from page JavaScript; it is distinct from HTTP status codes and request failures.

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.

Observe request and response stages

Puppeteer emits request and response events without request interception. A request event marks a request being issued, a response event indicates that a response arrived, and requestfinished means the response body has been downloaded and the request completed.

page.on('request', request => {
  console.log('Request:', request.url());
});

page.on('response', response => {
  console.log('Response:', response.url(), response.status());
});

page.on('requestfinished', request => {
  console.log('Finished:', request.url());
});

page.on('requestfailed', request => {
  console.log('Failed:', request.url(), request.failure()?.errorText);
});

An HTTP error status is still an HTTP response. A 404 or 503 request can receive a response and finish normally; it does not become requestfailed just because the status is unsuccessful. A failed network request instead emits requestfailed rather than requestfinished. Redirects finish one request and issue another request to the redirected URL. See Puppeteer’s network logging guide.

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

Use request interception only when you need control

Do not enable interception merely to observe traffic. Use page.setRequestInterception(true) when you need to alter, continue, answer, or abort requests. Once enabled, requests stall until resolved, unless completed using the browser cache.

await page.setRequestInterception(true);

page.on('request', request => {
  if (request.isInterceptResolutionHandled()) return;

  if (request.url().endsWith('.png')) {
    request.abort();
  } else {
    request.continue();
  }
});

When interception handlers include asynchronous work, another handler may resolve the request while the first is awaiting. Check isInterceptResolutionHandled() immediately before resolving it, and keep the check and resolution together synchronously. This prevents a second resolution attempt. The request interception guide explains the resolution behavior.

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

Understand lifecycle events versus navigation wait conditions

networkidle0 and networkidle2 are navigation wait conditions, not Page event names. They wait for the number of active network connections to remain under the relevant limit for at least 500 ms. They can be useful when a page needs time to settle, but pages with ongoing network activity may not reach that condition. Choose a wait strategy based on the page behavior you need to observe rather than treating network idle as a universal signal that all content is ready. See the lifecycle event reference.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common listener problems and fixes

  • The listener does not run: Register it before the action that may trigger the event. For navigation waits, pair the wait with the triggering action using Promise.all.
  • page.off() does not remove it: Pass the original callback reference, not a new arrow function with identical code.
  • A 404 does not emit requestfailed: That is expected; a 404 is an HTTP response. Inspect response.status() to detect HTTP errors.
  • A frame event fires unexpectedly: framenavigated can refer to an iframe. Check whether the frame is page.mainFrame() when only the top-level URL matters.
  • An intercepted request errors or stalls: Make sure every intercepted request is continued, responded to, or aborted, and check that another handler has not already resolved it.
  • networkidle0 is rejected as an event name: Use it as a navigation lifecycle wait condition, not with page.on().

Check event availability in your Puppeteer version

The official Page API reference surfaced for Puppeteer 25.12.0 and identifies Page as an EventEmitter. The PageEvent enum reference is under the next documentation, so confirm event names and payloads against the documentation for the version installed in your project before relying on an event in production.

Or skip the browser setup

If your goal is a screenshot rather than browser-side event handling, ScreenshotNeo can return an image or PDF with one GET request. Its screenshot flow accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. ScreenshotNeo also offers an MCP server with screenshot, page-info, and PDF tools for AI agents. The free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots.

Example using cURL (replace the URL with the page to capture):

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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. Sign up for 1,000 free screenshots a month with no card.

Frequently Asked Questions

Does page.on('load') wait for navigation?

No. It registers a listener for the event; use a navigation wait API when your code must await navigation.

Is networkidle0 a Page event?

No. It is a lifecycle wait condition based on active network connections.

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.

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

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.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver 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.