Skip to main content
Good prompts make Stagehand reliable. Bad prompts cause failures. Here’s how to write prompts that work consistently.

Act Method

Use act() for single actions on web pages. Each action should be focused and clear.
// Good - Single, specific actions
await stagehand.act("click the 'Add to Cart' button");
await stagehand.act("type 'user@example.com' into the email field");

// Bad - Multiple actions combined
await stagehand.act("fill out the form and submit it");
await stagehand.act("login with credentials and navigate to dashboard");

Use Element Types, Not Colors

Describe elements by their type and function rather than visual attributes like color.
// Good - Element types and descriptive text
await stagehand.act("click the 'Sign In' button");
await stagehand.act("type into the email input field");

// Bad - Color-based descriptions
await stagehand.act("click the blue button");
await stagehand.act("type into the white input");

Use Descriptive Language

// Good - Clear element identification
await stagehand.act("click the 'Next' button at the bottom of the form");
await stagehand.act("type into the search bar at the top of the page");

// Bad - Vague descriptions
await stagehand.act("click next");
await stagehand.act("type into search");

Choose the Right Action Verbs

  • Click for buttons, links, checkboxes
  • Type for text inputs
  • Select for dropdowns
  • Check/uncheck for checkboxes
  • Upload for file inputs
// Good
await stagehand.act("click the submit button");
await stagehand.act("select 'Option 1' from dropdown");

// Bad
await stagehand.act("click submit");
await stagehand.act("choose option 1");

Protect Sensitive Data

Variables keep sensitive information out of prompts and logs.
// Use variables for sensitive data
await stagehand.act("type %username% into the email field", {
  variables: { username: "user@example.com" }
});

await stagehand.act("type %password% into the password field", {
  variables: { password: process.env.USER_PASSWORD }
});
Set verbose: 0 in your Stagehand config to prevent secrets from appearing in logs.

Extract Method

Use extract() to pull structured data from pages. Define clear schemas and provide context.

Schema Best Practices

Use descriptive field names, correct types, and detailed descriptions. Field descriptions provide context that helps the model understand exactly what to extract.
// Good - Descriptive names, correct types, and helpful descriptions
const productData = await stagehand.extract(
  "Extract product information",
  z.object({
    productTitle: z.string().describe("The main product name displayed on the page"),
    priceInDollars: z.number().describe("Current selling price as a number, without currency symbol"),
    isInStock: z.boolean().describe("Whether the product is available for purchase")
  })
);

// Bad - Generic names, wrong types, no descriptions
const data = await stagehand.extract(
  "Get product details",
  z.object({
    name: z.string(), // Too generic, no context
    price: z.string(), // Should be number
    stock: z.string() // Should be boolean, no context
  })
);

Use Proper URL Types

Specify URL types with z.string().url() to tell Stagehand to extract URLs.
// Good - Tells Stagehand to extract URLs
const links = await stagehand.extract(
  "Extract navigation links",
  z.array(z.object({
    text: z.string(),
    url: z.string().url() // Required for URL extraction
  }))
);

// Single URL extraction
const contactUrl = await stagehand.extract(
  "extract the contact page URL",
  z.string().url()
);

Observe Method

Use observe() to discover actionable elements before acting on them.

Check Elements First

Verify elements exist before taking action to avoid errors.
// Check for elements first
const loginButtons = await stagehand.observe("Find the login button");

if (loginButtons.length > 0) {
  await stagehand.act(loginButtons[0]);
} else {
  console.log("No login button found");
}

Be Specific About Element Types

// Good - Specific element types
const submitButtons = await stagehand.observe("Find submit button in the form");
const dropdowns = await stagehand.observe("Find the state dropdown menu");

// Bad - Too vague
const elements = await stagehand.observe("Find submit stuff");
const things = await stagehand.observe("Find state selection");

Agent Method

Use agent() for complex, multi-step workflows. Provide detailed instructions and set appropriate limits. Don’t include navigation in agent tasks. Handle it separately.
// Good - Navigate first
await page.goto('https://amazon.com');
await agent.execute('Search for wireless headphones under $100 and add the best rated one to cart');

// Bad - Navigation in task
await agent.execute('Go to Amazon, search for headphones, and add one to cart');

Be Highly Specific

Detailed instructions lead to better results.
// Good - Detailed instructions
await agent.execute({
  instruction: "Find Italian restaurants in Brooklyn that are open after 10pm, have outdoor seating, and are rated 4+ stars. Save the top 3 results.",
  maxSteps: 25
});

// Bad - Vague instructions
await agent.execute("Find some good restaurants");

Set Appropriate Step Limits

Match step limits to task complexity.
// Simple task - fewer steps
await agent.execute({
  instruction: "Subscribe to the newsletter with email 'user@example.com'",
  maxSteps: 10
});

// Complex task - more steps  
await agent.execute({
  instruction: "Research and compare 5 project management tools with pricing and features",
  maxSteps: 50
});

Include Success Criteria

Tell the agent how to know when it’s done.
// Good - Clear success criteria
await agent.execute({
  instruction: "Add 3 smartphone cases to cart and confirm the cart shows exactly 3 items with total price",
  maxSteps: 20
});

// Bad - No validation
await agent.execute("Add some items to cart");

Common Mistakes to Avoid

  • Combining multiple actions - Keep each act() call to one action
  • Using vague descriptions - Be specific about which elements to interact with
  • Exposing sensitive data - Always use variables for credentials
  • Skipping validation - Check results before proceeding

Testing Your Prompts

  1. Start simple - Test basic functionality first
  2. Add complexity gradually - Build up to complex workflows
  3. Monitor results - Use logging to understand what’s happening
  4. Iterate based on failures - Refine prompts when they don’t work Remember: Good prompting is iterative. When in doubt, be more specific rather than less.