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().
#1 Best Overall
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
- 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().
Recommended Free Tools
Rank #3
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
- 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
responseis null:goto()can return null forabout:blankor a same-URL hash navigation. Use optional chaining before calling response methods; usepage.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 frompage.url()orresponse?.url(). - The URL differs from the one returned by the response: The page may have navigated again after
goto()resolved. Readpage.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 causegoto()to throw in headless shell.
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:
Quick Recap
Best Value
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.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteProduct 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.

