Skip to main content

Overview

The page object is the main interface for interacting with browser pages in Stagehand. It provides standard browser automation capabilities for navigation, interaction, and page inspection. Access the page object through your Stagehand instance:
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
const page = stagehand.context.pages()[0];

goto()

Navigate the page to a URL and wait for a lifecycle state.
await page.goto(url: string, options?: GotoOptions): Promise<Response | null>
Returns a Response when the navigation produces a network document request, otherwise null (e.g. data: URLs or same-document navigations).
url
string
required
The URL to navigate to. Can be absolute or relative.
waitUntil
LoadState
When to consider navigation succeeded.Options:
  • "load" - Wait for the load event
  • "domcontentloaded" - Wait for DOMContentLoaded event (default)
  • "networkidle" - Wait for network to be idle
Default: "domcontentloaded"
timeoutMs
number
Maximum time to wait for navigation in milliseconds.Default: 15000

reload()

Reload the current page.
await page.reload(options?: ReloadOptions): Promise<Response | null>
Resolves with a Response for the refreshed document when one is reported, otherwise null.
waitUntil
LoadState
When to consider reload complete. See goto() for options.
timeoutMs
number
Maximum time to wait for reload in milliseconds.Default: 15000
ignoreCache
boolean
Whether to bypass the browser cache.Default: false

goBack()

Navigate back in browser history.
await page.goBack(options?: NavigationOptions): Promise<Response | null>
Returns a Response when the history entry triggers a network fetch; otherwise null.
waitUntil
LoadState
When to consider navigation complete.
timeoutMs
number
Maximum time to wait in milliseconds.Default: 15000

goForward()

Navigate forward in browser history.
await page.goForward(options?: NavigationOptions): Promise<Response | null>
Returns a Response when the navigation loads a new document from the network; otherwise null.
waitUntil
LoadState
When to consider navigation complete.
timeoutMs
number
Maximum time to wait in milliseconds.Default: 15000

Page Information

url()

Get the current page URL (synchronous).
page.url(): string
Returns: The current page URL as a string.

title()

Get the current page title.
await page.title(): Promise<string>
Returns: The page title as a string.

Interaction Methods

click()

Click at absolute page coordinates.
await page.click(x: number, y: number, options?: ClickOptions): Promise<string>
Returns: A string containing the XPath of the clicked element when returnXpath is true, otherwise an empty string.
x
number
required
X coordinate in CSS pixels.
y
number
required
Y coordinate in CSS pixels.
options
object
Optional click configuration.

hover()

Hover at absolute page coordinates without clicking.
await page.hover(x: number, y: number, options?: HoverOptions): Promise<string>
Returns: A string containing the XPath of the hovered element when returnXpath is true, otherwise an empty string.
x
number
required
X coordinate in CSS pixels.
y
number
required
Y coordinate in CSS pixels.
options
object
Optional hover configuration.

scroll()

Scroll at absolute page coordinates using mouse wheel events.
await page.scroll(x: number, y: number, deltaX: number, deltaY: number, options?: ScrollOptions): Promise<string>
Returns: A string containing the XPath of the element at the scroll position when returnXpath is true, otherwise an empty string.
x
number
required
X coordinate in CSS pixels where the scroll occurs.
y
number
required
Y coordinate in CSS pixels where the scroll occurs.
deltaX
number
required
Horizontal scroll amount in pixels. Positive values scroll right.
deltaY
number
required
Vertical scroll amount in pixels. Positive values scroll down.
options
object
Optional scroll configuration.

dragAndDrop()

Drag from one position to another using mouse events.
const [fromXpath, toXpath] = await page.dragAndDrop(fromX, fromY, toX, toY, options?)
Returns: An array of two strings containing the XPaths of the elements at the start and end positions when returnXpath is true, otherwise empty strings.
fromX
number
required
Starting X coordinate in CSS pixels.
fromY
number
required
Starting Y coordinate in CSS pixels.
toX
number
required
Ending X coordinate in CSS pixels.
toY
number
required
Ending Y coordinate in CSS pixels.
options
object
Optional drag configuration.

type()

Type text into the page (dispatches keyboard events).
await page.type(text: string, options?: TypeOptions): Promise<void>
text
string
required
The text to type.
options
object
Optional typing configuration.

locator()

Create a locator for querying elements.
page.locator(selector: string): Locator
selector
string
required
CSS selector or XPath for the element.
Returns: A Locator object for interacting with the element.

Evaluation

evaluate()

Evaluate JavaScript code in the page context.
await page.evaluate<R, Arg>(
  pageFunctionOrExpression: string | ((arg: Arg) => R | Promise<R>),
  arg?: Arg
): Promise<R>
pageFunctionOrExpression
string | function
required
JavaScript expression as a string or a function to execute in the page context.
arg
any
Optional argument to pass to the function.
Returns: The result of the evaluation (must be JSON-serializable).

Initialization Scripts

addInitScript()

Inject JavaScript that runs before any of the page’s scripts on every navigation.
await page.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, reference a preload 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 for the current page (including adopted iframe sessions) on every navigation
  • Reinstalls the script for all future navigations of this page without affecting other pages
  • Mirrors Playwright’s page.addInitScript() ordering semantics; use context.addInitScript() to target every page in the context
import { Stagehand } from "@browserbasehq/stagehand";

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

await page.addInitScript(() => {
  window.Math.random = () => 42;
});

await page.goto("https://example.com", { waitUntil: "load" });

const result = await page.evaluate(() => Math.random());
console.log("Math.random() returned:", result);

// Math.random() returned: 42

Screenshot

screenshot()

Capture a screenshot of the page.
await page.screenshot(options?: ScreenshotOptions): Promise<Buffer>
fullPage
boolean
Capture the entire scrollable page instead of just the current viewport.Default: false
clip
ScreenshotClip
Limit the capture to the provided rectangle in CSS pixels ({ x, y, width, height }). Cannot be combined with fullPage.
type
'png' | 'jpeg'
Image format for the screenshot.Default: "png"
quality
number
JPEG quality (0–100). Only used when type is "jpeg".
scale
'css' | 'device'
Rendering scale. Use "css" for one pixel per CSS pixel, or "device" for the device pixel ratio.Default: "device"
animations
'allow' | 'disabled'
Control CSS/Web animations and transitions. "disabled" fast-forwards finite animations and pauses infinite ones before capture.Default: "allow"
caret
hide | initial
Hide the text caret during capture ("hide") or leave it untouched ("initial").Default: "hide"
mask
Locator[]
List of locators to cover with a colored overlay while the screenshot is taken.
maskColor
string
CSS color to use for masked overlays.Default: #FF00FF
style
string
Additional CSS text injected into every frame just before capture. Useful for hiding or tweaking dynamic UI.
omitBackground
boolean
Make the default page background transparent (PNG only).Default: false
timeout
number
Maximum time in milliseconds to wait for the capture before throwing.
path
string
Write the screenshot to the provided file path. The image is still returned as a buffer.
Returns: A Promise<Buffer> containing the screenshot image data.

Page Snapshot

snapshot()

Capture a structured accessibility snapshot of the current page. The returned data combines a human-readable accessibility tree with lookup maps so you can relate each node to DOM selectors or URLs.
await page.snapshot(options?: PageSnapshotOptions): Promise<SnapshotResult>
options
PageSnapshotOptions
Optional configuration for the snapshot.
Returns: A Promise<SnapshotResult> describing the captured accessibility tree. See SnapshotResult for the static type definition. The formatted tree represents every accessibility node with:
  • A unique encoded ID in brackets (e.g., [0-1]) for cross-referencing with the maps
  • The node’s accessibility role (RootWebArea, heading, link, button, etc.)
  • The node’s accessible name, when available
Example formatted output:
[0-1] RootWebArea: Example Domain
  [0-3] heading: Example Domain
  [0-5] paragraph: This domain is for use in illustrative examples in documents.
  [0-8] link: More information...
Example usage:
const page = stagehand.context.pages()[0];
await page.goto("https://example.com");

const { formattedTree, xpathMap, urlMap } = await page.snapshot();

// Print the accessibility tree
console.log(formattedTree);

// Look up a specific element's XPath by encoded ID
const linkId = "0-8";
console.log(xpathMap[linkId]); // e.g., "/html/body/div/p[2]/a"

// Resolve a link's URL via the urlMap
console.log(urlMap[linkId]); // e.g., "https://www.example.com"

// Exclude iframe content when you only need the main document
const mainDocumentSnapshot = await page.snapshot({ includeIframes: false });

Viewport

setViewportSize()

Set the page viewport size.
await page.setViewportSize(
  width: number,
  height: number,
  options?: ViewportOptions
): Promise<void>
width
number
required
Viewport width in CSS pixels.
height
number
required
Viewport height in CSS pixels.
deviceScaleFactor
number
Device scale factor (pixel ratio).Default: 1

Wait Methods

waitForLoadState()

Wait for the page to reach a specific lifecycle state.
await page.waitForLoadState(state: LoadState, timeoutMs?: number): Promise<void>
state
LoadState
required
The lifecycle state to wait for.Options: "load", "domcontentloaded", "networkidle"
timeoutMs
number
Maximum time to wait in milliseconds.Default: 15000

waitForSelector()

Wait for an element matching the selector to reach a specific state in the DOM. Uses a MutationObserver for efficiency, pierces shadow DOM by default, and supports iframe hops when needed.
await page.waitForSelector(
  selector: string,
  options?: {
    state?: "attached" | "detached" | "visible" | "hidden";
    timeout?: number;
    pierceShadow?: boolean;
  }
): Promise<boolean>
selector
string
required
CSS selector or XPath expression to wait for. Supports iframe hops (e.g., /html/div/iframe/html/div/button).
options
object
Optional wait configuration.
Returns: true when the condition is met. Throws: Error if timeout is reached before the condition is met.

Events

on(“console”)

Listen for console output produced by the page and any adopted iframe sessions. Returns the page instance so calls can be chained.
import type { ConsoleMessage } from "@browserbasehq/stagehand";

const handleConsole = (message: ConsoleMessage) => {
  console.log(`[${message.type()}] ${message.text()}`);
  console.log("Arguments:", message.args());
  const location = message.location();
  if (location?.url) {
    console.log(`Emitted from ${location.url}:${location.lineNumber ?? 0}`);
  }
};

page.on("console", handleConsole);
ConsoleMessage exposes helpers for working with console events:
  • message.type() – console API category such as log, error, or warning
  • message.text() – string representation of the console arguments
  • message.args() – underlying CDP RemoteObject arguments array
  • message.location() – source URL, line, and column when available
  • message.timestamp() – CDP timestamp for the event
  • message.raw() – access to the original Runtime.consoleAPICalledEvent

once(“console”)

Register a listener that removes itself after the first console event.
page.once("console", (message) => {
  console.log("First console message:", message.text());
});

off(“console”)

Remove a previously registered listener. The reference must match the original listener passed to on().
page.off("console", handleConsole);

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 page = stagehand.context.pages()[0];

// Navigate to a URL
await page.goto("https://example.com");

// Get current URL and title
console.log("URL:", page.url());
console.log("Title:", await page.title());

// Navigate back and forward
await page.goBack();
await page.goForward();

// Reload the page
await page.reload();

Types

LoadState

type LoadState = "load" | "domcontentloaded" | "networkidle";
  • "load" - Wait for the load event (all resources loaded)
  • "domcontentloaded" - Wait for the DOMContentLoaded event (DOM is ready)
  • "networkidle" - Wait for network connections to be idle

AnyPage

type AnyPage = PlaywrightPage | PuppeteerPage | PatchrightPage | Page;
Stagehand supports multiple browser automation libraries. The AnyPage type represents any compatible page object.

ScreenshotClip

interface ScreenshotClip {
  x: number;
  y: number;
  width: number;
  height: number;
}
Represents the CSS-pixel rectangle to capture when clip is provided.

ScreenshotOptions

interface ScreenshotOptions {
  fullPage?: boolean;
  clip?: ScreenshotClip;
  type?: "png" | "jpeg";
  quality?: number;
  scale?: "css" | "device";
  animations?: "allow" | "disabled";
  caret?: "hide" | "initial";
  mask?: Locator[];
  maskColor?: string;
  style?: string;
  omitBackground?: boolean;
  timeout?: number;
  path?: string;
}
Matches Playwright’s screenshot signature with sensible defaults to control how a capture is produced.

PageSnapshotOptions

type PageSnapshotOptions = {
  includeIframes?: boolean;
};
  • includeIframes - Whether to include iframe content in the snapshot. Defaults to true

SnapshotResult

type SnapshotResult = {
  formattedTree: string;
  xpathMap: Record<string, string>;
  urlMap: Record<string, string>;
};
  • formattedTree - A formatted string representation of the page’s accessibility tree with encoded IDs, roles, and names
  • xpathMap - A mapping from encoded element IDs to their absolute XPath selectors
  • urlMap - A mapping from encoded element IDs to their associated URLs (for links and other navigable elements)

Error Handling

Page methods may throw the following errors:
  • Navigation Errors - Timeout or network issues during navigation
  • Evaluation Errors - JavaScript execution errors in evaluate()
  • Interaction Errors - Failed clicks or typing operations
  • Screenshot Errors - Issues capturing screenshots
All errors should be caught and handled appropriately:
try {
  await page.goto("https://example.com");
} catch (error) {
  console.error("Navigation failed:", error.message);
}