Documentation Index Fetch the complete documentation index at: https://mintlify.com/browserbase/stagehand/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The observe() method identifies elements on the page that match a description. It returns an array of Action objects that can be used with act() or inspected directly.
Syntax
const actions = await stagehand . observe ();
const actions = await stagehand . observe ( instruction , options ? );
Parameters
Natural language description of elements to find If omitted, returns all interactive elements on the page Examples:
"buttons on the page"
"the submit button"
"all links in the navigation menu"
"form input fields"
Override the default model Format: "provider/model" or { modelName, ...clientOptions }
Maximum time to wait (milliseconds)
CSS selector to scope search to specific elements
page
Page | PlaywrightPage | PuppeteerPage | PatchrightPage
Page to observe (defaults to active page)
Returns
Array of Action objects representing found elements Selector to target the element (XPath or CSS)
Human-readable description of the element
Suggested DOM method to call (e.g., “click”, “fill”)
Suggested method arguments
Examples
Find All Interactive Elements
import { Stagehand } from "@browserbasehq/stagehand" ;
const stagehand = new Stagehand ({ env: "LOCAL" });
await stagehand . init ();
const page = await stagehand . context . newPage ();
await page . goto ( "https://example.com" );
// Get all interactive elements
const actions = await stagehand . observe ();
console . log ( `Found ${ actions . length } interactive elements` );
actions . forEach (( action , i ) => {
console . log ( ` ${ i + 1 } . ${ action . description } ` );
});
await stagehand . close ();
Find Specific Elements
// Find buttons
const buttons = await stagehand . observe ( "buttons on the page" );
console . log ( `Found ${ buttons . length } buttons` );
// Find specific button
const submitButtons = await stagehand . observe ( "the submit button" );
if ( submitButtons . length > 0 ) {
console . log ( "Submit button found:" , submitButtons [ 0 ]. description );
}
// Find form fields
const inputs = await stagehand . observe ( "input fields in the form" );
Use with act()
// Find element first, then act on it
const actions = await stagehand . observe ( "the login button" );
if ( actions . length > 0 ) {
const result = await stagehand . act ( actions [ 0 ]);
console . log ( "Clicked:" , result . message );
}
Inspect Element Details
const actions = await stagehand . observe ( "all navigation links" );
actions . forEach (( action ) => {
console . log ( "Description:" , action . description );
console . log ( "Selector:" , action . selector );
console . log ( "Method:" , action . method );
console . log ( "---" );
});
Scoped Observation
// Only look within header
const headerButtons = await stagehand . observe ( "buttons" , {
selector: "header" ,
});
// Only look within specific form
const formInputs = await stagehand . observe ( "input fields" , {
selector: "#login-form" ,
});
Find Multiple Element Types
// Find all links
const links = await stagehand . observe ( "links on the page" );
// Find all buttons
const buttons = await stagehand . observe ( "buttons on the page" );
// Find all form inputs
const inputs = await stagehand . observe ( "form input fields" );
// Find all dropdowns
const dropdowns = await stagehand . observe ( "dropdown menus" );
With Custom Model
const actions = await stagehand . observe ( "interactive elements" , {
model: "anthropic/claude-3-5-sonnet-latest" ,
});
Multi-page Observation
const page1 = await stagehand . context . newPage ();
const page2 = await stagehand . context . newPage ();
await page1 . goto ( "https://example.com" );
await page2 . goto ( "https://another.com" );
// Observe on specific pages
const actions1 = await stagehand . observe ( "buttons" , { page: page1 });
const actions2 = await stagehand . observe ( "buttons" , { page: page2 });
console . log ( `Page 1 buttons: ${ actions1 . length } ` );
console . log ( `Page 2 buttons: ${ actions2 . length } ` );
Real-World Examples
Find and Click Menu Items
const menuItems = await stagehand . observe ( "menu items in the navigation" );
// Find specific menu item
const settingsMenu = menuItems . find (( item ) =>
item . description . toLowerCase (). includes ( "settings" )
);
if ( settingsMenu ) {
await stagehand . act ( settingsMenu );
}
Find Form Fields and Fill Them
const formFields = await stagehand . observe (
"input fields in the registration form"
);
for ( const field of formFields ) {
console . log ( `Found field: ${ field . description } ` );
if ( field . description . includes ( "email" )) {
await stagehand . act ( `type 'user@example.com' in this field` , {
page: /* current page */ ,
});
}
}
Validate Page Elements
// Check if required elements exist
const requiredButtons = [
"submit button" ,
"cancel button" ,
"help button" ,
];
for ( const buttonDesc of requiredButtons ) {
const found = await stagehand . observe ( buttonDesc );
if ( found . length === 0 ) {
console . error ( `Missing: ${ buttonDesc } ` );
} else {
console . log ( `✓ Found: ${ buttonDesc } ` );
}
}
const footerLinks = await stagehand . observe ( "links in the footer" , {
selector: "footer" ,
});
const linkDescriptions = footerLinks . map (( link ) => link . description );
console . log ( "Footer links:" , linkDescriptions );
Find Dynamic Elements
// Wait for page to load
await page . waitForLoadState ( "networkidle" );
// Find elements that may have loaded dynamically
const dynamicButtons = await stagehand . observe (
"action buttons in the modal dialog"
);
if ( dynamicButtons . length > 0 ) {
console . log ( "Modal is open" );
await stagehand . act ( dynamicButtons [ 0 ]);
}
Compare Pages
const page1Actions = await stagehand . observe ( "buttons" , { page: page1 });
const page2Actions = await stagehand . observe ( "buttons" , { page: page2 });
const diff = {
onlyInPage1: page1Actions . length - page2Actions . length ,
page1Buttons: page1Actions . map (( a ) => a . description ),
page2Buttons: page2Actions . map (( a ) => a . description ),
};
console . log ( "Difference:" , diff );
Best Practices
Be specific in descriptions :
// Good
observe ( "the blue submit button in the form" )
// Less specific
observe ( "button" )
Check array length before using :
const actions = await stagehand . observe ( "login button" );
if ( actions . length > 0 ) {
await stagehand . act ( actions [ 0 ]);
}
Use scoped selectors for efficiency :
// Faster and more accurate
observe ( "buttons" , { selector: ".toolbar" })
Combine with act() for reliable workflows :
const element = await stagehand . observe ( "specific button" );
if ( element . length > 0 ) {
await stagehand . act ( element [ 0 ]);
}
Inspect element properties :
const actions = await stagehand . observe ( "all links" );
actions . forEach (( action ) => {
console . log ( `Element: ${ action . description } ` );
console . log ( `Selector: ${ action . selector } ` );
});
Use for validation and testing :
// Verify expected elements exist
const requiredElements = await stagehand . observe ( "required elements" );
expect ( requiredElements . length ). toBeGreaterThan ( 0 );