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

Enable request interception with await page.setRequestInterception(true), then pass an override object to request.continue() in the request handler. Puppeteer documents four override fields: headers, method, postData, and url. Every intercepted request must be resolved, and handlers that share interception should guard against resolving the same request twice.

Enable interception before continuing requests

HTTPRequest.continue() requires request interception. Enable it on the page before relying on a request handler to change or continue traffic:

await page.setRequestInterception(true);

With interception enabled, a request stalls until it is continued, responded to, aborted, or completed through the browser cache. Puppeteer’s guide warns that a request can hang if request.continue() is not called explicitly when continuation is intended. See the Puppeteer Request Interception guide and Page.setRequestInterception() reference.

Change a request and let it proceed

This example adds a header to matching requests and continues all other requests unchanged. It also checks whether another handler has already resolved the request before acting.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.setRequestInterception(true);

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

  if (request.url().includes('/api/')) {
    const headers = {
      ...request.headers(),
      'x-example': 'value',
    };

    return request.continue({ headers });
  }

  return request.continue();
});

The listener uses Puppeteer’s documented pattern: copy the existing headers, add the desired field, then pass the resulting object to continue(). Header names from request.headers() are lower-case. For exact behavior on a particular release, check the installed version: the official HTTPRequest.continue() reference surfaced as version 25.12.0, while the ContinueRequestOverrides interface reference surfaced as version 25.10.0.

Choose the override field that matches the change

Field What it changes Example
headers Request headers, supplied as an object. { headers: { ...request.headers(), 'x-example': 'value' } }
method HTTP method. { method: 'POST' }
postData Request body as a string. { postData: 'key=value' }
url Request URL. Puppeteer says changing it is not a redirect. { url: 'https://example.test/replacement-path' }

These are the optional properties documented by Puppeteer’s ContinueRequestOverrides interface. A combined override can look like this:

request.continue({
  url: 'https://example.test/replacement-path',
  method: 'POST',
  postData: 'key=value',
});

Add or remove a header

Copy the current headers if you want to preserve them, then set the header you need. To remove a header, Puppeteer’s documented example sets its value to undefined:

const headers = {
  ...request.headers(),
  origin: undefined,
};

request.continue({ headers });

Read an existing request body carefully

request.postData() can be undefined when the body is too long or is not readily available in decoded form, even if the request has a body. The HTTPRequest class reference points to fetchPostData() for that situation. This caveat concerns reading the original body; the continuation override separately accepts postData as a string.

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

Handle multiple request handlers and priorities

If your application registers more than one request handler, another handler may continue, abort, or respond to a request before yours does. Check request.isInterceptResolutionHandled() before resolving it to avoid duplicate actions.

request.continue(overrides, priority) accepts an optional priority after the override object. In cooperative interception, Puppeteer’s guide recommends priority 0 or DEFAULT_INTERCEPT_RESOLUTION_PRIORITY for an unopinionated continuation. A deliberately opinionated priority can be used when a handler is meant to prevail over a lower-priority abort or response. Choose the priority based on how your handlers are intended to cooperate; do not add one as a substitute for resolving every request.

Troubleshoot common failures

  • continue() throws immediately: confirm interception was enabled with await page.setRequestInterception(true) on the page.
  • Navigation or page loading appears stuck: inspect every path through the request handler. With interception enabled, intercepted requests wait until resolved; make sure each request that should proceed reaches continue(), and requests meant to stop are deliberately aborted or responded to.
  • A request is resolved twice: check for additional listeners or middleware that also handles interception, then guard with request.isInterceptResolutionHandled().
  • A header unexpectedly disappears or changes: build from request.headers() when preserving existing headers matters; use lower-case names as returned by Puppeteer.
  • postData() returns undefined: the body may be too long or unavailable in decoded form. Consult the HTTPRequest reference for fetchPostData(); do not assume that a missing decoded value means the request had no body.
  • Another handler wins or loses unexpectedly: review cooperative interception priorities and whether your continuation is unopinionated or intended to override another resolution.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup:

For a website screenshot rather than custom Puppeteer request logic, ScreenshotNeo returns a screenshot or PDF from one GET request. Its capture flow accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before taking the shot; those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, with response headers indicating the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients.

cURL:

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 documentation for API details. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, with no card.

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

Sources and version note

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.