Skip to main content

Stagehand

Learn about the main Stagehand object

Clipboard

Learn about reading, writing, copying, cutting, and pasting clipboard text

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.

Properties

clipboard

Access the browser clipboard API for the active page or a specific page.
context.clipboard: BrowserClipboard
Use context.clipboard to read and write clipboard text, paste into focused elements, or copy and cut selected content. See the clipboard reference for the full API.

Code Examples

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

// Initialize with Browserbase (API key from environment variable)
// Set BROWSERBASE_API_KEY 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;
}