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

After page.goto() resolves, call page.url() to read the page’s current URL. Use the returned response’s url() when you need the URL tied specifically to that navigation response, and inspect redirectChain() when you need the earlier requests.

Get the final page URL with page.url()

For the ordinary case—finding where a navigation ended—read the page URL after goto() completes:

const response = await page.goto('https://example.com');
const finalUrl = page.url();

console.log(finalUrl);

page.url() returns the current page URL and is a shortcut for page.mainFrame().url(). Puppeteer documents that goto() resolves with the response of the last redirect when a navigation follows multiple redirects. Together, these APIs make page.url() the straightforward way to read the destination after navigation.

Choose the right URL API

What you need Use What it tells you
The page’s current URL page.url() The URL currently shown by the page’s main frame.
The URL associated with the navigation response response?.url() The URL of the response returned by goto().
The earlier requests in a redirect chain response?.request().redirectChain() ?? [] The requests that were redirected along the way; this is history, not the destination URL.

These methods answer related but distinct questions. The current page URL can change after the original navigation—for example, if client-side code later navigates the page. The navigation response URL remains tied to the response returned by goto().

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

Read the navigation response URL

If your code needs the URL attached to the navigation response rather than the page’s current URL, use response?.url():

const response = await page.goto('https://example.com');
const responseUrl = response?.url();

console.log(responseUrl);

Page.goto() returns Promise<HTTPResponse | null>. The optional chaining handles cases where there is no response object, including navigation to about:blank and navigation to the same URL with only a hash change.

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

Inspect the redirect history

To see which requests were redirected, get the request’s redirect chain from the navigation response:

const response = await page.goto('http://example.com');
const redirects = response?.request().redirectChain() ?? [];
const finalUrl = page.url();

console.log('Redirected requests:', redirects.map(request => request.url()));
console.log('Final page URL:', finalUrl);

redirectChain() returns the requests that were redirected, not the final destination. For a single redirect from http://example.com to https://example.com, the chain contains the original HTTP request. With no redirects, it is empty. Read the destination separately with page.url() or response?.url().

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

Check navigation status separately

A resolved navigation does not by itself establish that the server returned a successful HTTP status. Puppeteer documents that, in headless shell, goto() does not throw for valid HTTP status codes such as 404 or 500. If status matters to your application, inspect it:

const response = await page.goto('https://example.com');
const status = response?.status();

if (status === undefined) {
  console.log('No navigation response to inspect.');
} else if (status >= 400) {
  console.error(`HTTP error status: ${status}`);
} else {
  console.log(`HTTP status: ${status}`);
}

An HTTP error response is different from a network or request failure: a 404 or 503 is still an HTTP response. Handle the response status and navigation failures as separate conditions.

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

Troubleshoot common cases

  • response is null: goto() can return null for about:blank or a same-URL hash navigation. Use optional chaining before calling response methods; use page.url() for the current page URL.
  • The chain is empty: An empty redirectChain() means no requests were redirected in that chain. It does not mean the final URL is unavailable; read it from page.url() or response?.url().
  • The URL differs from the one returned by the response: The page may have navigated again after goto() resolved. Read page.url() after the later navigation has finished if you need the current destination.
  • The navigation completed but the page is an error: Check response?.status(). A valid HTTP error status such as 404 or 500 need not cause goto() to throw in headless shell.
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 you need a screenshot rather than Puppeteer’s navigation URL, ScreenshotNeo returns an image or PDF from one GET request. Its API accepts a URL and can return PNG, JPEG, WebP, or PDF output. For example, save a WebP screenshot of the destination URL you want to capture:

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

See the ScreenshotNeo API documentation for request options. Cookie banners, newsletter popups, and chat widgets are removed before capture; bot checks, blank pages, and failed loads are not billed. An MCP server lets AI agents take screenshots, and the free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for ScreenshotNeo.

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.