How to Use Puppeteer Browser Contexts for Isolated Sessions
Create Puppeteer browser contexts to keep cookies, localStorage, and cache separate. Learn to manage pages, cookies, popups, cleanup, and common errors.
browser.createBrowserContext() creates a new Puppeteer browser context. Pages created with context.newPage() use that context, whose cookies, localStorage, and cache are separate from other browser contexts. Close the context with context.close() when the session ends; this closes its associated pages. Contexts organize browser state, but the documented isolation does not promise separation of every browser resource or provide a security boundary.
1. Create and close an isolated session
Launch a browser, create a context for the session, then create pages through that context. Use try/finally so a failed navigation or other error does not leave the context or browser running.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const context = await browser.createBrowserContext();
try {
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
console.log(await page.title());
} finally {
await context.close();
}
} finally {
await browser.close();
}
Save this as an ES module, for example session.mjs, and run it in an environment where Puppeteer and its browser are installed. A launched browser has a default context already. Use createBrowserContext() when you need a separate session; in Chrome, non-default contexts are incognito. The default context cannot be closed with context.close().
The calls shown here are the current Puppeteer API names. The official reference says a newly created context “won’t share cookies/cache with other browser contexts.” See Browser.createBrowserContext() and the BrowserContext reference.
2. Put every session page in its context
Call context.newPage() for every page that should share this session’s context-scoped state. A page created another way may be in a different context. Popups opened by a page, such as through window.open(), remain in the parent page’s context.
const context = await browser.createBrowserContext();
try {
const accountPage = await context.newPage();
const helpPage = await context.newPage();
await Promise.all([
accountPage.goto('https://example.com/account'),
helpPage.goto('https://example.com/help'),
]);
// Both pages belong to this context.
// A popup opened by either page also belongs to this context.
} finally {
await context.close(); // closes both pages and associated popups
}
Choose the scope deliberately: pages that need to share a login session belong in the same context; independent sessions should use separate contexts. Puppeteer describes browser contexts as individual user contexts. Its documented storage examples include cookies and localStorage; context creation also documents that contexts do not share cache. Do not infer from this that every browser-level resource is isolated. See the browser management guide.
3. Manage cookies at context level
Use the context cookie API when inspecting, setting, or removing cookies for a session. Puppeteer marks the page-level cookie methods deprecated and points to browser- or context-level methods instead.
// Read cookies associated with this context's pages.
const currentCookies = await context.cookies();
console.log(currentCookies.map(({ name, domain }) => ({ name, domain })));
// Set a cookie before navigating, or while the context is active.
await context.setCookie({
name: 'session_hint',
value: 'example',
domain: 'example.com',
path: '/',
secure: true,
httpOnly: true,
sameSite: 'Lax',
});
// Remove cookies by their identifying properties using the context's
// cookie deletion API supported by your installed Puppeteer version.
// Check the BrowserContext reference for the exact method signature.
Cookie validity still depends on normal cookie rules such as domain, path, secure transport, and expiry. A cookie for one host will not automatically apply to another. Set cookies with attributes appropriate to the site and navigation you intend to automate.
The BrowserContext API includes cookies(), setCookie(), and cookie deletion methods. Consult its versioned API reference for the deletion method’s current signature rather than relying on deprecated page cookie calls. The Page API documents the deprecation.
4. Handle multiple sessions and cleanup
For independent users or tasks, create one context per session and close each one when finished. Closing a context closes its pages; it does not close the browser. Close the browser separately when the whole automation process is done.
const contexts = [];
try {
for (const url of ['https://example.com/a', 'https://example.com/b']) {
const context = await browser.createBrowserContext();
contexts.push(context);
const page = await context.newPage();
await page.goto(url, { waitUntil: 'domcontentloaded' });
}
} finally {
await Promise.all(contexts.map((context) => context.close()));
}
In a long-running worker, use a try/finally per task so one failure does not skip cleanup of that task’s context. If you maintain a pool of reusable contexts, make the reuse policy explicit: reuse means the same context-scoped state can persist between tasks until cleared or the context is closed.
5. Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Cookies or localStorage appear shared | The pages were created in the same context, or one was created in the default context. | Create a distinct context for each independent session, and create its pages with context.newPage(). |
| A popup appears to belong to the wrong session | The opener page was already in that context. | Popups inherit the parent page’s browser context. Open them from a page created in the intended context. |
| Closing a context throws or is unavailable | The code is trying to close the default context. | Only close contexts created for the session. Close the browser with browser.close() when browser shutdown is intended. |
| Cookie is not sent to the site | Its domain, path, secure flag, or expiry does not match the target request. | Set attributes for the target host and use HTTPS when the cookie is marked secure. Inspect the context’s cookies while diagnosing. |
| Page-level cookie API shows a deprecation warning | The Page cookie methods are deprecated. | Use the corresponding browser- or context-level cookie methods documented for your Puppeteer version. |
| Navigation hangs or fails | The destination is slow, unreachable, or waiting for a load condition that never occurs. | Set an appropriate navigation timeout and wait condition, handle the navigation error, and keep context cleanup in finally. |
6. Performance, reliability, and security boundaries
Puppeteer’s cited documentation provides no benchmark for creating one context per task versus reusing pages or contexts. Each additional context represents another isolated session to manage, so choose the smallest scope that matches the state separation your workflow needs and measure resource use in your own workload.
- Reliability: close contexts in
finally, including when navigation or extraction throws. Close the browser during process shutdown. - State hygiene: create separate contexts for independent cookie, localStorage, and cache state. Reusing a context also reuses its session scope.
- Boundaries: the API documents storage isolation, not full process isolation or a security guarantee for untrusted tenants. Do not treat a context alone as a security boundary.
- Cost: Puppeteer itself is a browser automation library; infrastructure and execution costs depend on where and how you run the browser. No cost or speed figures are established by the cited documentation.
7. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. If your task is to capture a page rather than interact with a browser session, a single request returns an image or PDF. See the API documentation for parameters.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never 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 per month with no card; paid plans start at $5 for 3,000.
Sign up for 1,000 free screenshots a month with no card.
8. FAQ
Do separate browser contexts share cookies?
Puppeteer documents that a newly created context does not share cookies with other browser contexts.
Does closing a context close the browser?
No. It closes that context and its associated pages. Use browser.close() to close the browser.
Can two pages in one context share a session?
Yes. Create both with the same context’s newPage() method; they belong to that context.
Are contexts a security boundary for untrusted sites or tenants?
The cited API documents storage isolation. It does not establish complete browser-resource isolation or a security guarantee.


