Skip to main content

Overview

The context object manages the browser context, which is a container for multiple pages (tabs). It provides methods for creating new pages, accessing existing pages, and managing which page is currently active. Access the context through your Stagehand instance:
const stagehand = new Stagehand({ env: "BROWSERBASE" });
await stagehand.init();
const context = stagehand.context;

Methods

newPage()

Create a new page (tab) in the browser.
await context.newPage(url?: string): Promise<Page>
url
string
The URL to navigate to in the new page.Default: "about:blank"
Returns: Promise<Page> - The newly created page object. The new page is automatically set as the active page.

pages()

Get all open pages in the browser context.
context.pages(): Page[]
Returns: Page[] - Array of all open pages, ordered from oldest to newest.

activePage()

Get the currently active page.
context.activePage(): Page | undefined
Returns: Page | undefined - The most recently used page, or undefined if no pages exist. The active page is determined by:
  1. Most recently interacted with page
  2. Most recently created page if no interaction history
  3. undefined if all pages have been closed

setActivePage()

Set a specific page as the active page.
context.setActivePage(page: Page): void
page
Page
required
The page to set as active. Must be a page that exists in this context.
This method:
  • Marks the page as most recently used
  • Brings the tab to the foreground (in headed mode)
  • Makes it the default page for subsequent operations

addInitScript()

Inject JavaScript that runs before any page scripts on every navigation.
await context.addInitScript<Arg>(
  script: string | { path?: string; content?: string } | ((arg: Arg) => unknown),
  arg?: Arg,
): Promise<void>
script
string | { path?: string; content?: string } | (arg: Arg) => unknown
required
Provide the script to inject. Pass raw source code, reference a file on disk, or supply a function that Stagehand serializes before sending to the browser.
arg
Arg
Extra data that is JSON-serialized and passed to your function. Only supported when script is a function.
This method:
  • Runs at document start, and installs the script on all currently open pages and replays it on every navigation of those pages
  • Automatically applies the same script to any pages created after calling context.addInitScript()
  • Allows referencing preload files via { path: "./preloads/dom-hooks.js" }, mirroring Playwright’s sourceURL behavior for readable stack traces
import { Stagehand } from "@browserbasehq/stagehand";

const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
const context = stagehand.context;

// Add some JavaScript to automatically accept alert dialogs
await context.addInitScript(() => {
   window.alert = () => {};
   window.confirm = () => true;
   window.prompt = () => '';
 });

setExtraHTTPHeaders()

Set HTTP headers that will be included in every request made by all pages in the browser context.
await context.setExtraHTTPHeaders(headers: Record<string, string>): Promise<void>
headers
Record<string, string>
required
A plain object of header name–value pairs. All values must be strings.
This method:
  • Applies the headers to all existing pages in the context immediately
  • Automatically applies the same headers to any pages created after calling setExtraHTTPHeaders()
  • Calling it again replaces all previously set extra headers (it does not merge)
  • To clear all extra headers, pass an empty object: await context.setExtraHTTPHeaders({})
Headers set via context.setExtraHTTPHeaders() are context-wide. They apply to every network request from every page in the context, including navigation requests, XHR/fetch calls, and subresource loads.
import { Stagehand } from "@browserbasehq/stagehand";

const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
const context = stagehand.context;

// Set custom headers for all requests
await context.setExtraHTTPHeaders({
  "X-Custom-Token": "my-secret-token",
  "Accept-Language": "en-US",
});

// All subsequent requests from any page in this context
// will include these headers
const page = await context.newPage("https://example.com");

cookies()

Retrieve browser cookies, optionally filtered by URL(s).
await context.cookies(urls?: string | string[]): Promise<Cookie[]>
urls
string | string[]
A single URL or array of URLs to filter cookies by. When provided, only cookies that match the domain, path, and secure requirements of the given URLs are returned.Default: Returns all cookies when omitted.
Returns: Promise<Cookie[]> - Array of cookie objects.
// Get all cookies
const allCookies = await context.cookies();

// Get cookies for a specific URL
const siteCookies = await context.cookies("https://example.com");

// Get cookies for multiple URLs
const cookies = await context.cookies([
  "https://example.com",
  "https://api.example.com",
]);

addCookies()

Set one or more cookies in the browser context.
await context.addCookies(cookies: CookieParam[]): Promise<void>
cookies
CookieParam[]
required
Array of cookie parameters to set. Each cookie must provide either url or both domain and path — providing both url and domain (or url and path) will throw a validation error.
Cookies set via context.addCookies() are shared across all pages in the context, scoped by domain and path.
// Set a cookie using a URL
await context.addCookies([
  {
    name: "session",
    value: "abc123",
    url: "https://example.com",
  },
]);

// Set a cookie using domain and path
await context.addCookies([
  {
    name: "token",
    value: "xyz789",
    domain: ".example.com",
    path: "/",
    secure: true,
    httpOnly: true,
    sameSite: "Strict",
  },
]);
Setting sameSite: "None" requires secure: true. Stagehand will throw a validation error if this requirement is not met.

clearCookies()

Clear cookies from the browser context. Can clear all cookies or selectively filter by name, domain, or path.
await context.clearCookies(options?: ClearCookieOptions): Promise<void>
options
ClearCookieOptions
Filter options to selectively clear cookies. When omitted, all cookies are cleared.
// Clear all cookies
await context.clearCookies();

// Clear cookies by exact name
await context.clearCookies({ name: "session" });

// Clear cookies by domain pattern
await context.clearCookies({ domain: /\.example\.com$/ });

// Combine filters (a cookie must match ALL provided filters to be cleared)
await context.clearCookies({
  name: "token",
  domain: ".example.com",
});

close()

Close the browser context and all associated pages.
await context.close(): Promise<void>
This method:
  • Closes the CDP connection
  • Cleans up all pages
  • Clears all internal mappings
Note: This is typically called internally by stagehand.close(). You usually don’t need to call this directly.

Code Examples

import { Stagehand } from "@browserbasehq/stagehand";

// Initialize with Browserbase (API key and project ID from environment variables)
// Set BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID in your environment
const stagehand = new Stagehand({ env: "BROWSERBASE" });
await stagehand.init();
const context = stagehand.context;

// Create a new page
const page1 = await context.newPage("https://example.com");
console.log("Created page 1");

// Create another page
const page2 = await context.newPage("https://another-site.com");
console.log("Created page 2");

// Get all pages
const allPages = context.pages();
console.log(`Total pages: ${allPages.length}`);

await stagehand.close();

Working with Active Pages

The context tracks which page is currently active:
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();

// Get the current active page
const activePage = stagehand.context.activePage();

// Create a new page - it becomes active
const newPage = await stagehand.context.newPage();

// Now context.activePage() returns newPage
await newPage.goto("https://example.com");

Relationship Between Context and Page

  • Context manages the browser-level state and multiple pages
  • Page represents a single tab/window with content
  • Creating a new page via context.newPage() automatically sets it as active
  • You can explicitly control the active page with context.setActivePage()
  • Use context.activePage() to get the currently active page
// Get the active page
const activePage = stagehand.context.activePage();

// Or get the first page directly
const firstPage = stagehand.context.pages()[0];

Best Practices

  1. Create pages explicitly - Use context.newPage() instead of relying on popups or window.open
  2. Track page references - Store page objects in variables for easier management
  3. Set active page before operations - Ensure the correct page is active before calling Stagehand methods
  4. Clean up properly - Call stagehand.close() to close all pages and the context
  5. Handle page order - Remember that context.pages() returns pages in creation order
  6. Use parallel operations - Work with multiple pages simultaneously for better performance

Common Patterns

Tab Management

// Keep track of pages by purpose
const pages = {
  home: await context.newPage("https://example.com"),
  dashboard: await context.newPage("https://example.com/dashboard"),
  settings: await context.newPage("https://example.com/settings")
};

// Switch between tabs
context.setActivePage(pages.dashboard);
await stagehand.act("view report");

context.setActivePage(pages.settings);
await stagehand.act("update preferences");

Bulk Data Collection

const urls = [
  "https://site1.com",
  "https://site2.com",
  "https://site3.com"
];

// Open all pages
const pages = await Promise.all(
  urls.map(url => context.newPage(url))
);

// Extract data from each
const data = await Promise.all(
  pages.map(page => stagehand.extract("get data", schema, { page }))
);

Conditional Page Management

// Only create a page if needed
if (needsDashboard) {
  const dashboard = await context.newPage("https://example.com/dashboard");
  context.setActivePage(dashboard);
  await stagehand.act("generate report");
}

// Check if we have multiple pages
if (context.pages().length > 1) {
  console.log("Multiple tabs open");
}

Error Handling

Context methods may throw the following errors:
  • Timeout errors - newPage() timeout waiting for page to attach
  • CDP errors - Connection errors with Chrome DevTools Protocol
  • Invalid page errors - Attempting to set an active page that doesn’t exist in the context
  • StagehandSetExtraHTTPHeadersError - setExtraHTTPHeaders() failed to apply headers to one or more sessions. The error includes a failures array with per-session details
Always handle errors appropriately:
try {
  const page = await context.newPage("https://example.com");
} catch (error) {
  console.error("Failed to create page:", error.message);
}

Type Definitions

interface V3Context {
  newPage(url?: string): Promise<Page>;
  pages(): Page[];
  activePage(): Page | undefined;
  setActivePage(page: Page): void;
  setExtraHTTPHeaders(headers: Record<string, string>): Promise<void>;
  cookies(urls?: string | string[]): Promise<Cookie[]>;
  addCookies(cookies: CookieParam[]): Promise<void>;
  clearCookies(options?: ClearCookieOptions): Promise<void>;
  close(): Promise<void>;
}

interface Cookie {
  name: string;
  value: string;
  domain: string;
  path: string;
  /** Unix time in seconds. -1 means session cookie. */
  expires: number;
  httpOnly: boolean;
  secure: boolean;
  sameSite: "Strict" | "Lax" | "None";
}

interface CookieParam {
  name: string;
  value: string;
  /** If provided, domain/path/secure are derived from this URL. */
  url?: string;
  domain?: string;
  path?: string;
  /** Unix timestamp in seconds. -1 or omitted = session cookie. */
  expires?: number;
  httpOnly?: boolean;
  secure?: boolean;
  sameSite?: "Strict" | "Lax" | "None";
}

interface ClearCookieOptions {
  name?: string | RegExp;
  domain?: string | RegExp;
  path?: string | RegExp;
}