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:
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.
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.
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.
Maps encoded IDs for link-like nodes to their resolved URLs.
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:
Copy
Ask AI
[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:
Copy
Ask AI
const page = stagehand.context.pages()[0];await page.goto("https://example.com");const { formattedTree, xpathMap, urlMap } = await page.snapshot();// Print the accessibility treeconsole.log(formattedTree);// Look up a specific element's XPath by encoded IDconst linkId = "0-8";console.log(xpathMap[linkId]); // e.g., "/html/body/div/p[2]/a"// Resolve a link's URL via the urlMapconsole.log(urlMap[linkId]); // e.g., "https://www.example.com"// Exclude iframe content when you only need the main documentconst mainDocumentSnapshot = await page.snapshot({ includeIframes: false });
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.
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 environmentconst stagehand = new Stagehand({ env: "BROWSERBASE" });await stagehand.init();const page = stagehand.context.pages()[0];// Navigate to a URLawait page.goto("https://example.com");// Get current URL and titleconsole.log("URL:", page.url());console.log("Title:", await page.title());// Navigate back and forwardawait page.goBack();await page.goForward();// Reload the pageawait page.reload();
// Execute JavaScript expressionconst pageHeight = await page.evaluate("document.body.scrollHeight");console.log("Page height:", pageHeight);// Execute function with argumentsconst result = await page.evaluate((selector) => { const element = document.querySelector(selector); return element ? element.textContent : null;}, "h1");console.log("H1 text:", result);// Async function evaluationconst data = await page.evaluate(async () => { const response = await fetch("/api/data"); return response.json();});
Copy
Ask AI
// Click at coordinatesawait page.click(100, 200);// Double clickawait page.click(100, 200, { clickCount: 2 });// Click and get the XPath of the clicked elementconst xpath = await page.click(100, 200, { returnXpath: true });console.log("Clicked element xpath:", xpath); // e.g., "/html/body/div[1]/button"// Hover at coordinatesawait page.hover(300, 150);// Hover and get the XPath of the hovered elementconst hoverXpath = await page.hover(300, 150, { returnXpath: true });// Scroll down at a positionawait page.scroll(400, 300, 0, 200); // scroll down 200px// Drag and drop between two pointsconst [fromXpath, toXpath] = await page.dragAndDrop(100, 100, 300, 300, { returnXpath: true });// Type textawait page.type("Hello, World!");// Type with delay between keystrokesawait page.type("Slow typing", { delay: 100 });// Use locator for element interactionconst button = page.locator("button.submit");await button.click();
Copy
Ask AI
// Navigate and wait for full loadawait page.goto("https://example.com", { waitUntil: "load", timeoutMs: 30000});// Wait for network idle after navigationawait page.goto("https://spa-app.com", { waitUntil: "networkidle"});// Wait for specific load stateawait page.waitForLoadState("domcontentloaded");
Copy
Ask AI
// Wait for element to be visible (default)await page.waitForSelector("#submit-btn");// Wait for element to appear with custom timeoutawait page.waitForSelector(".loading-spinner", { state: "visible", timeout: 10000});// Wait for element to be removed from DOMawait page.waitForSelector(".loading-spinner", { state: "detached"});// Wait for element to become hiddenawait page.waitForSelector(".modal", { state: "hidden"});// Wait for element inside an iframeawait page.waitForSelector("iframe#checkout >> .pay-button");// Wait for element in shadow DOM (enabled by default)await page.waitForSelector("#shadow-button", { pierceShadow: true});// Wait for element with XPathawait page.waitForSelector("/html/div/button");
Copy
Ask AI
// Set viewport sizeawait page.setViewportSize(1920, 1080);// Set mobile viewport with device scaleawait page.setViewportSize(375, 667, { deviceScaleFactor: 2});// Then take a screenshot at this sizeconst screenshot = await page.screenshot();
Copy
Ask AI
// Capture the page's accessibility tree snapshotconst { formattedTree, xpathMap, urlMap } = await page.snapshot();// The formattedTree shows the page structure:// [0-1] RootWebArea: Example Domain// [0-3] heading: Example Domain// [0-8] link: More information...console.log(formattedTree);// Use xpathMap to get the XPath selector for any element by IDconst linkXpath = xpathMap["0-8"];console.log("Link XPath:", linkXpath); // "/html/body/div/p[2]/a"// Use urlMap to get URLs associated with link elementsconst linkUrl = urlMap["0-8"];console.log("Link URL:", linkUrl); // "https://www.iana.org/domains/example"// Exclude iframe content from the snapshotconst mainPageOnly = await page.snapshot({ includeIframes: false });