ScreenshotNeo

BlogHow-to

How to Get and Manage Cookies with Puppeteer

Read, set, and delete cookies with Puppeteer. Learn how cookie scope, browser contexts, and cleanup affect reliable tests.

By the ScreenshotNeo team4 October 20269 min read

Puppeteer exposes cookie operations on both Browser and BrowserContext. Use await browser.cookies() to read cookies in the default context, await browser.setCookie(...cookies) to add or update them, and await browser.deleteCookie(...cookies) to remove specified cookies. For isolated test state, create a separate browser context and use its cookie methods. A cookie’s domain, path, security attributes, and expiry must match the site and browser behavior you intend to test.

This guide uses Puppeteer’s browser-level and context-level cookie APIs. Check the API reference for your installed Puppeteer version when using browser-specific fields. Puppeteer cookie guide · Browser API · BrowserContext API.

1. Install Puppeteer and start a browser

In a new Node.js project, install Puppeteer. The package manages a compatible Chrome for Testing browser as part of its installation flow.

npm init -y
npm install puppeteer

Save the following as cookies.mjs and run it with node cookies.mjs. It navigates to a page, prints its cookies, sets a cookie for that page, reads the result, and removes the cookie before closing the browser.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
try {
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });

  // Browser cookie methods operate on the default BrowserContext.
  console.log('Before:', await browser.cookies());

  await browser.setCookie({
    name: 'automation-example',
    value: 'present',
    url: 'https://example.com/',
    path: '/',
    secure: true,
    sameSite: 'Lax',
  });

  console.log('After:', await browser.cookies());

  // Delete using the cookie identity, including its scope.
  await browser.deleteCookie({
    name: 'automation-example',
    domain: 'example.com',
    path: '/',
  });
  console.log('Cleaned up:', await browser.cookies());
} finally {
  await browser.close();
}

The url field lets Puppeteer derive defaults such as domain, path, and source scheme. The guide’s cookie example uses explicit domain and path instead. Choose the form that makes the intended scope clear for your test, and inspect the returned cookies to confirm what the browser stored.

2. Read cookies

Read cookies available to the default context

browser.cookies() returns the cookies available in Puppeteer’s default BrowserContext. This is convenient for a simple script that uses the default context:

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

Use await context.cookies() when you need the cookie jar for a particular context. Cookie values can contain session credentials or other sensitive state; avoid logging them in shared CI logs or production output.

Read cookies associated with a page

For page-oriented code, use the page’s context rather than assuming the browser’s default context is the one that owns the page:

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

Cookie visibility is governed by browser cookie rules and the context’s storage. A cookie scoped to a different domain or path may not be available for the URL you are checking. HttpOnly cookies are still browser cookies; JavaScript running in the page cannot read them, but Puppeteer’s browser cookie API can return their attributes.

3. Set cookies

Pass one or more cookie data objects to setCookie. The required fields are name and value; scope and attributes should reflect the application’s expected behavior.

await context.setCookie(
  {
    name: 'session-hint',
    value: 'test-session',
    url: 'https://app.example.com/',
    httpOnly: true,
    secure: true,
    sameSite: 'Lax',
  },
  {
    name: 'theme',
    value: 'dark',
    url: 'https://app.example.com/',
    path: '/',
    sameSite: 'Lax',
  },
);

A successful call means the browser accepted the operation; it does not guarantee the application will accept the value as a valid login or session. Authentication cookies may be signed, encrypted, short-lived, or bound to server-side state. For login tests, prefer the application’s supported test authentication flow or a valid test session issued by the server.

Field Purpose and considerations
name, value Required cookie key and stored value.
url Page-level cookie parameter. Can determine default domain, path, and source-scheme values. Use a URL for the target origin when relying on defaults.
domain Cookie domain scope. Match the host or parent-domain behavior required by the application; a leading dot may be represented in returned data depending on browser behavior.
path Path scope. Use / when the cookie should apply throughout the host, if that matches the application’s intended cookie.
expires Expiration time as a number. If omitted, the cookie is a session cookie. Use the format expected by the Puppeteer version and browser API; do not assume a duration in seconds is interpreted as a relative lifetime.
httpOnly When true, page JavaScript cannot read the cookie through document.cookie. Browser automation can still manage it through Puppeteer.
secure Restricts transmission to secure contexts according to browser rules. Match the real site’s transport requirements.
sameSite Cross-site request policy. Puppeteer’s documented values are browser API values such as Strict, Lax, or None; None generally needs secure handling in modern browsers.
partitionKey Partitioned-cookie key where supported. Browser support and accepted shape can vary; consult the versioned API reference.
priority, sourceScheme Documented as Chrome-supported fields. Do not assume these are portable across browser engines.

The current CookieData reference documents the browser-level fields, and the CookieParam reference documents the page-level url option. Match the installed Puppeteer release and browser when relying on less portable attributes.

4. Delete cookies and clean up state

Use deleteCookie when you know which cookie identity to remove. Cookie scope matters: specify the identifying fields, especially name, domain, and path, so the browser can target the intended cookie.

await context.deleteCookie({
  name: 'session-hint',
  domain: 'app.example.com',
  path: '/',
});

To remove cookies by filters, use deleteMatchingCookies on a BrowserContext. This is useful for scoped cleanup when a test should clear matching cookies without enumerating them first.

await context.deleteMatchingCookies({
  domain: 'app.example.com',
});

See the deleteMatchingCookies API reference for the accepted filter fields in your release. Browser-level deleteCookie is a shortcut for the default BrowserContext; context methods affect that context’s jar.

Cookie cleanup does not clear all browser state. If the goal is a fully fresh test, consider using a new context or also clearing local storage, session storage, caches, and other state through the appropriate browser or application mechanisms.

5. Isolate cookies with BrowserContext

Browser contexts isolate storage, including cookies and local storage. Use a new context for each independent test or user session so one test’s cookie mutations do not leak into another. In Chrome, Puppeteer’s non-default browser contexts are incognito contexts. Closing a context closes its pages; the default context cannot be closed.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
try {
  const context = await browser.createBrowserContext();
  try {
    const page = await context.newPage();
    await context.setCookie({
      name: 'test-mode',
      value: 'enabled',
      url: 'https://example.com/',
    });
    await page.goto('https://example.com');
    console.log(await context.cookies());
  } finally {
    await context.close();
  }
} finally {
  await browser.close();
}

Create a context per test when isolation is more important than the small setup cost. Reuse a context when a sequence deliberately shares authenticated state, but make the sharing explicit and clean it up after use.

Need Recommended approach
Inspect the default session await browser.cookies()
Manage a specific test/user session Create a BrowserContext and call its cookie methods
Preload a test cookie Set it with a matching URL or explicit domain and path before navigating to the page that needs it
Remove known cookies Pass cookie identity details to deleteCookie
Clear cookies matching a criterion Use deleteMatchingCookies on the intended context
Reset all context storage Close the context and create a fresh one

7. Common errors and fixes

Symptom Likely cause Fix
Cookie does not appear after setting The URL/domain is invalid for the browser context or fields are inconsistent. Set against the target site’s HTTPS URL, or specify a valid matching domain and path. Read the cookies back immediately and inspect the browser’s accepted attributes.
Cookie exists but is not sent with a request Domain, path, expiry, Secure, or SameSite rules prevent it from applying. Compare the cookie attributes with the request URL and top-level site context. Use values that match the real application instead of weakening attributes blindly.
Page JavaScript cannot see the cookie The cookie is HttpOnly, or the current page does not match its scope. Use Puppeteer’s cookie API to inspect it. For page access, use a non-HttpOnly cookie only if that matches the application’s intended design.
Delete call leaves a cookie behind The deletion identity omitted or mismatched the cookie’s domain/path, or another cookie with the same name has a different scope. Read the cookie list, copy its relevant identity fields, and delete each scoped cookie; alternatively use a context filter.
Cookie is present but authentication still fails The application requires a valid server-issued token, related cookies, CSRF state, or other storage. Use a supported test login/session mechanism and reproduce the full required state. A fabricated cookie value does not create a valid server session.
Cookie methods affect the wrong page or test Browser-level shortcuts target the default context, while the page belongs to another context. Call the methods on page.browserContext() or retain and use the exact context that created the page.
Unsupported option or TypeScript mismatch The installed Puppeteer/browser version differs from the reference or field support is browser-specific. Check the versioned API docs and installed type definitions. Treat priority and sourceScheme as Chrome-specific per the reference.
Cookie appears to expire immediately The expiry value was interpreted as an absolute timestamp, or it is already in the past. Check the expected numeric expiry format for your version and provide a future timestamp. Omit expiry for a session cookie.

8. Reliability, speed, and cost considerations

Cookie operations are local browser state changes, but the behavior they control depends on a live site, its server, and browser cookie policy. Keep tests deterministic by using a known browser version, an isolated context, valid test credentials, and a cleanup path in finally blocks. Avoid sharing one context across parallel tests that mutate the same cookie names.

For speed, reuse a browser process across a suite when appropriate, while creating fresh contexts for isolated sessions. This avoids repeatedly launching Chrome while retaining context-level separation. Navigation and page loading usually take longer than the cookie API calls; choose a navigation wait condition based on the page behavior rather than waiting for every possible network connection indefinitely.

Puppeteer is an open-source browser automation library; these examples do not involve a per-cookie service charge. Operational costs come from running the browser and the infrastructure around it, such as CI time and compute. Keep browser concurrency within available memory and CPU, and ensure browser processes and contexts are closed even when a test fails.

9. Or skip the browser setup

If your goal is to capture a page rather than automate cookie behavior, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF; see the 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);

ScreenshotNeo accepts cookie and consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.

10. FAQ

Does Puppeteer return HttpOnly cookies?

Yes. Puppeteer’s browser cookie API can inspect HttpOnly cookies even though page JavaScript cannot read them through document.cookie.

Set it before navigating when the initial request needs to include it. Make sure the cookie’s URL or domain and path cover the destination.

Does deleting cookies clear local storage too?

No. Cookies and local storage are separate storage. Use a fresh context when you need an isolated storage environment.

No. A cookie only works if the site accepts its value and any required related state. Use a valid test session issued by the application.