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

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Wait for the navigation (and any redirect chain) to finish, then read cookies from the BrowserContext that owns your page:

const response = await page.goto('https://example.com/start');
const cookies = await page.browserContext().cookies();
console.log(cookies);

This returns the cookies currently stored in that context after the navigation sequence. Use browser.cookies() only when you intentionally want the default browser context. The older page.cookies() method is deprecated and has URL-scoped behavior.

Read the final cookie state after page.goto()

Install and run the example with a current Puppeteer release, and verify the API labels for the version you deploy. The official documentation pages consulted for this guide show labels 25.10.0, 25.11.0 and 25.12.0 on different references; those labels are not a promise that all pages were released together.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npm install puppeteer
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com/start', {
      waitUntil: 'networkidle2',
      timeout: 90_000
    });

    // Reads every cookie in the context that owns this page.
    const cookies = await page.browserContext().cookies();
    console.log(cookies);
  } finally {
    await browser.close();
  }
})();

page.goto() resolves after Puppeteer completes the navigation it is tracking, including redirects issued by the server. Querying the context afterward lets the browser’s cookie store reflect the resulting state instead of an intermediate response.

Do not assume that the value returned by page.goto() is always non-null. The reliable operation for this task is to await navigation and then query context storage.

When a click starts the redirect

A click-driven navigation has a race: the click can start loading before your code begins waiting. Start both promises together, as shown in Puppeteer’s navigation guidance:

const [response] = await Promise.all([
  page.waitForNavigation({
    waitUntil: 'networkidle2',
    timeout: 90_000
  }),
  page.click('a.continue')
]);

const cookies = await page.browserContext().cookies();
console.log(cookies);
  1. Create the navigation wait first. Put page.waitForNavigation() in the Promise.all() array before the click.
  2. Trigger the click. Puppeteer can now observe the navigation from its beginning.
  3. Read context cookies after both promises resolve. At that point, the redirect sequence has completed according to the chosen lifecycle condition.

If the page uses a form submission or JavaScript navigation, replace page.click() with the action that causes it, while keeping the same synchronization pattern.

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

Choose the cookie API by context scope

API What it reads When to use it
page.browserContext().cookies() All cookies in the BrowserContext that owns the page Preferred default, especially when you create incognito or otherwise separate contexts
browser.cookies() All cookies in the browser’s default context Convenient shortcut when the page definitely runs in the default context
page.cookies(...urls) Cookies filtered for the current page URL or supplied URLs Legacy compatibility only; the Page API reference marks this method obsolete

A browser can contain several isolated contexts. Cookies and local storage do not cross those boundaries. If you created a context with browser.createBrowserContext() (or the current equivalent in your Puppeteer version), obtain cookies through that context or through a page belonging to it:

const context = await browser.createBrowserContext();
const page = await context.newPage();
await page.goto('https://example.com/start', { waitUntil: 'networkidle2' });
const cookies = await context.cookies();
// The equivalent page-scoped call is:
// const cookies = await page.browserContext().cookies();

A popup opened by that page belongs to its parent page’s context, so querying the parent context is also the correct way to see the popup’s cookies.

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 redirects separately from cookies

Cookie retrieval and redirect diagnostics answer different questions. To see which requests were redirected, inspect the response returned by page.goto() and its request chain:

const response = await page.goto('https://example.com/start', {
  waitUntil: 'networkidle2'
});

if (response) {
  const chain = response.request().redirectChain();
  console.log(chain.map(request => ({
    url: request.url(),
    method: request.method()
  })));
}

const cookies = await page.browserContext().cookies();

Puppeteer’s HTTPRequest documentation explains that when a request receives a redirect response, that request finishes and a new request is issued for the redirected URL. A one-redirect chain therefore contains the original request; a navigation without redirects has an empty chain. The chain helps explain what happened, but it is not a cookie-reading API.

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

Cookies set in a redirect response are placed in browser storage according to normal cookie rules. Reading the owning context after navigation is what reveals the resulting stored values.

Understand what a returned cookie contains

Each cookie object can include fields such as name, value, domain, path, expires, size, httpOnly, secure and sameSite, depending on the Chromium and Puppeteer version. Log only what you need, because values often contain session credentials:

for (const cookie of cookies) {
  console.log({
    name: cookie.name,
    domain: cookie.domain,
    path: cookie.path,
    expires: cookie.expires,
    secure: cookie.secure,
    httpOnly: cookie.httpOnly,
    sameSite: cookie.sameSite
  });
}

Never paste session-cookie values into build logs, issue trackers or chat. Treat a cookie that authenticates a user like a password.

Wait for the right completion condition

waitUntil controls when Puppeteer considers navigation complete; it does not change how cookies are stored.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • domcontentloaded returns after the initial HTML is parsed. Use it when the redirect and cookie are server-side and later assets are irrelevant.
  • load waits for the load event, including subresources that participate in that event.
  • networkidle2 waits until there are no more than two active network connections for the idle window. Analytics, polling and streaming pages can prevent or delay this condition.
  • networkidle0 requires no active connections and can hang on applications that keep sockets open.

If a site sets a cookie after client-side code runs, wait for a selector, an explicit delay, or an application event after navigation, then query the context:

await page.goto('https://example.com/start', { waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-app-ready]', { timeout: 30_000 });
const cookies = await page.browserContext().cookies();

Choose the narrowest condition that represents “ready” for your application. A longer wait is not automatically more correct.

Troubleshooting missing or unexpected cookies

The cookie list is empty

  • Wrong context: You queried browser.cookies() while the page is in a separate context. Use page.browserContext().cookies() or retain the context variable.
  • Navigation did not finish: Capture and handle timeout errors, then determine whether the page reached the point where the application sets its cookie.
  • Cookie scope excludes the URL: Domain and path rules can prevent a cookie from being sent to the URL you are inspecting, even though it exists in the context. Print the domain and path fields.
  • Client code has not run: Wait for a reliable selector or application signal before reading storage.

You read an old value

Make sure the click and navigation are synchronized with Promise.all(). Reading immediately after page.click() can race the redirect. Also check that a service worker, cache or application code is not restoring state later in the page lifecycle.

waitForNavigation() times out

The action may open a new tab, use history APIs without a traditional navigation, or leave persistent connections that defeat your chosen lifecycle. Listen for a new target when a popup is expected, or wait for a page-specific selector/state change when the URL does not navigate. Keep the cookie query tied to the event that actually means the application is ready.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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

The redirect chain is empty

An empty chain means the request represented by the response did not record a redirect. The page may have used client-side routing, a meta refresh, or no redirect at all. Cookie retrieval still works; redirect-chain inspection simply cannot describe a server redirect that did not occur on that request.

The deprecated API behaves differently

page.cookies() is URL-scoped and is marked obsolete in the official Page API. Migrate to page.browserContext().cookies() for context-wide storage, or use the browser shortcut when the default context is explicitly intended.

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

Performance, reliability and security considerations

Limit the amount of work

Reading cookies is inexpensive compared with launching Chromium and loading a page. Reuse a browser process when appropriate, but isolate unrelated sessions in separate contexts. Avoid repeatedly waiting for networkidle0 on sites with long-lived connections.

Make failures observable

Record the destination URL, navigation timeout and redirect-chain URLs, but redact cookie values. Distinguish a navigation timeout from an empty cookie jar; they require different fixes. Close pages and contexts in finally blocks so failed jobs do not leak resources.

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

Protect authentication state

Use a dedicated context per account or test. Do not share exported cookies between users, and do not commit cookie dumps to source control. If you must persist a session for testing, protect the file with the same controls used for credentials and delete it when the test ends.

Or skip the browser setup

If your actual goal is a rendered image or PDF rather than cookie inspection, ScreenshotNeo provides a single HTTP request without maintaining Puppeteer. Its preprocessing accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers report the page verdict and billing status. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

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 options such as full-page and element capture, device and retina settings, PDF controls, custom headers and cookies, waits, request blocking, caching, signed links, asynchronous jobs, bulk capture and usage reporting. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

FAQ

Does a redirect response expose cookies directly?

No. The response and redirect chain describe HTTP navigation; query Browser or BrowserContext storage for cookies.

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

Should I use the final URL when requesting cookies?

For the complete session state, use the owning context’s cookie method. URL-filtered retrieval is legacy behavior and can omit cookies outside the requested scope.

Can separate BrowserContexts share login cookies?

No. Contexts intentionally isolate cookies and local storage, so each context must authenticate independently or receive explicitly imported state.

Frequently Asked Questions

What is the safest default Puppeteer call?

After awaited navigation, call await page.browserContext().cookies() and handle the returned values as secrets.

How can I prove a server redirect happened?

Inspect response.request().redirectChain(); cookie retrieval itself does not report redirect history.

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.

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.