ScreenshotNeo

BlogHow-to

How to Get the URL of a Request in Puppeteer

Use Puppeteer’s request event and `request.url()` to log or filter URLs. Learn how redirects, interception, and common errors affect request logging.

By the ScreenshotNeo team4 October 20265 min read

Use Puppeteer’s request event and call url() on the HTTPRequest passed to the listener:

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

This observes requests without enabling request interception. The callback runs as the page issues requests, and request.url() returns the URL string for that request. See Puppeteer’s network logging guide and HTTPRequest.url() API reference.

Log every request URL

Register the listener before navigating so it can see requests triggered during the initial page load:

import puppeteer from 'puppeteer';

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

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

  await page.goto('https://example.com');
} finally {
  await browser.close();
}

Save this as an ES module, for example log-requests.mjs, in a project where Puppeteer is installed, then run it with Node.js. The listener covers requests issued by that page, including document and subresource requests. Puppeteer’s network logging guide demonstrates this event-based approach; observing requests does not require setRequestInterception().

Filter requests

Because request.url() returns a string, filter it in the listener using the condition relevant to your task:

page.on('request', request => {
  const url = request.url();
  if (url.includes('/api/')) {
    console.log('API request:', url);
  }
});

For a host-specific filter, parse the string as a URL:

page.on('request', request => {
  const url = new URL(request.url());
  if (url.hostname === 'api.example.com') {
    console.log(url.href);
  }
});

Parsing is useful when the query string or path should not affect the match. Choose whether to compare hostname, pathname, or another component based on what you mean by a match; substring checks can also match unintended URLs.

Request URL and response URL

A request event supplies an HTTPRequest; a response event supplies an HTTPResponse. Both expose a url() method. Use the request object to log the URL being requested, or the response object when handling a response:

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

The request and response events answer different questions: the former is about an issued request, while the latter is about a response associated with a URL. See the Puppeteer PageEvent API.

Redirects

Do not assume a redirect changes the URL on one request object. Puppeteer describes a redirect as a request that finishes successfully followed by a new request to the redirected URL. A request listener can therefore log both the original URL and the destination as separate requests. When investigating a redirect chain, keep each logged URL and its event context instead of treating the first URL as the final destination. See Puppeteer’s HTTPRequest API reference.

When request interception is needed

Interception is unnecessary for URL observation alone. Enable it when you need to modify, abort, or fulfill requests. When interception is on, requests stall until they are continued, responded to, aborted, or resolved through the browser cache. A logging-only interception handler that never resolves requests can prevent the page from loading. See the network interception guide.

await page.setRequestInterception(true);

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

If other listeners or asynchronous work may resolve the same intercepted request, check request.isInterceptResolutionHandled() before resolving it, and check again after an await. Another handler could resolve it while your handler is waiting.

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

  const url = request.url();
  await doSomethingAsync(url);

  if (request.isInterceptResolutionHandled()) return;
  await request.continue();
});

Use this guarded pattern only in an interception workflow. For ordinary logging, keep interception disabled and use the simpler request listener.

Operational notes

  • Register early: attach the listener before page.goto() if you need navigation and initial resource URLs.
  • Expect many events: a page can request scripts, stylesheets, images, fonts, and other resources. Filter or aggregate when you only need a subset.
  • Keep handlers quick: avoid slow synchronous work in the event callback. If you need asynchronous processing, design it so errors are handled and, with interception enabled, every request is still resolved.
  • Close the browser: put cleanup in a finally block so failures during navigation do not leave the browser process running.
  • Cost: Puppeteer itself does not bill by captured URL; account for the browser process and any network or infrastructure costs in your environment. This method does not call an external screenshot service.

Troubleshooting

Symptom Likely cause Fix
No URLs appear The listener was attached after navigation, or the page has not issued requests yet. Attach page.on('request', ...) before page.goto(). Confirm the page action you run actually causes a request.
The page hangs after enabling interception An intercepted request was not resolved. Call continue(), abort(), or respond() as appropriate for every intercepted request. Remove interception if you only need to observe URLs.
A URL appears more than once Separate requests can target the same URL, and redirects issue a subsequent request to another URL. Log additional request context if needed, and treat each event as a request rather than deduplicating by URL automatically.
Filtering includes unexpected matches A substring such as includes('/api/') can match a URL you did not intend. Parse the URL and compare its hostname or pathname explicitly.
request.continue() reports that the request was already handled Another interception handler resolved it, possibly while this handler awaited asynchronous work. Check isInterceptResolutionHandled() before and after the await, as shown above.

Or skip the browser setup

If your goal is to get a page image rather than inspect its network requests, ScreenshotNeo returns a screenshot or PDF from one API call. Its API does not expose Puppeteer request URLs; it handles the capture for you. The complete parameter and output options are in the ScreenshotNeo API documentation.

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

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
  • Cookie banners are accepted and removed before capture, along with 60+ known consent platforms, newsletter popups, and chat widgets; each step can be turned off.
  • Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Response headers report the page verdict and billing status.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
  • The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan.

Sign up for 1,000 free screenshots a month, with no card required.

FAQ

Does getting a request URL require interception?

No. The regular request event provides the request object. Interception is for controlling request behavior.

What type does request.url() return?

It returns the request URL as a string.

Will this log URLs from every page in the browser?

The listener is attached to one Puppeteer Page, so it observes requests from that page. Attach listeners to other pages separately if you need their requests too.

Can I use this to see which page URL a response came from?

Yes. In a response listener, use response.url() on the HTTPResponse.