Quickstart (Typescript)
Build AI agents that navigate the web using natural language instructions
This guide shows you how to use Stagehand with Steel browsers to create AI agents that can interact with websites using natural language commands. We'll build a simple automation that extracts data from Hacker News and demonstrates search functionality.
Prerequisites
Ensure you have the following:
-
Node.js 20 or higher
-
A Steel API key (sign up here)
-
An OpenAI API key (get one here)
Step 1: Set up your project
First, create a project directory and initialize your Node.js project:
# Create a project directorymkdir steel-stagehand-startercd steel-stagehand-starter# Initialize npm projectnpm init -y# Install required packagesnpm install @browserbasehq/stagehand dotenv steel-sdk typescript zod# Install dev dependenciesnpm install --save-dev @types/node ts-node
Create a .env
file with your API keys:
1# .env2STEEL_API_KEY=your_steel_api_key_here3OPENAI_API_KEY=your_openai_api_key_here4
Step 2: Create your data schemas
1import { Stagehand } from "@browserbasehq/stagehand";2import Steel from "steel-sdk";3import { z } from "zod";4import dotenv from "dotenv";56// Load environment variables7dotenv.config();89const STEEL_API_KEY = process.env.STEEL_API_KEY;10const OPENAI_API_KEY = process.env.OPENAI_API_KEY;1112// Define data schemas for structured extraction13const StorySchema = z.object({14title: z.string(),15rank: z.number()16});1718const StoriesSchema = z.object({19stories: z.array(StorySchema)20});21
These schemas will help Stagehand extract structured data from web pages using Zod validation.
Step 3: Create a Steel browser session
1async function main() {2console.log("๐ Steel + Stagehand Automation");3console.log("=".repeat(50));45// Initialize Steel client6const client = new Steel({7steelAPIKey: STEEL_API_KEY,8});910// Create a new browser session11const session = await client.sessions.create();1213console.log("โ Steel browser session created!");14console.log(`View live session at: ${session.sessionViewerUrl}`);15}16
When you run this, you'll see a URL where you can watch your browser session live.
Step 4: Configure and connect Stagehand
1// Configure Stagehand to use Steel session2const stagehand = new Stagehand({3env: "LOCAL",4localBrowserLaunchOptions: {5cdpUrl: `${session.websocketUrl}&apiKey=${STEEL_API_KEY}`,6},7enableCaching: false,8modelClientOptions: {9apiKey: OPENAI_API_KEY,10},11});1213// Initialize Stagehand14console.log("๐ค Initializing Stagehand...");15await stagehand.init();1617console.log("Connected to Steel browser via Stagehand");18
This connects Stagehand to your Steel browser session via Chrome DevTools Protocol.
Step 5: Navigate and extract data
Add the automation logic to navigate to a website and extract information:
1try {2// Navigate to Hacker News3console.log("๐ฐ Navigating to Hacker News...");4await stagehand.page.goto("https://news.ycombinator.com");56// Extract top stories using AI7console.log("๐ Extracting top stories...");8const stories = await stagehand.page.extract({9instruction: "extract the titles and ranks of the first 5 stories on the page",10schema: StoriesSchema,11});1213// Display results14console.log("\n๐ Top 5 Hacker News Stories:");15stories.stories.forEach((story, index) => {16console.log(`${story.rank}. ${story.title}`);17});1819console.log("\nโ Automation completed successfully!");2021} catch (error) {22console.error("โ Error during automation:", error);23}24
You'll see the extracted story titles and rankings printed to your console.
Step 6: Add proper cleanup
Always clean up your resources when finished:
1finally {2// Close Stagehand3if (stagehand) {4await stagehand.close();5}67// Release Steel session8if (session && client) {9await client.sessions.release(session.id);10console.log("๐งน Resources cleaned up");11}12}1314// Run the automation15main().catch((error) => {16console.error("Unhandled error:", error);17process.exit(1);18});19
Step 7: Run your automation
Execute your script:
You should see output like this:
๐ Steel + Stagehand Automation==================================================โ Steel browser session created!View live session at: https://api.steel.dev/v1/sessions/[session-id]/player๐ค Initializing Stagehand...Connected to Steel browser via Stagehand๐ฐ Navigating to Hacker News...๐ Extracting top stories...๐ Top 5 Hacker News Stories:1. Ask HN: What are you working on this week?2. Show HN: I built a tool to analyze my GitHub contributions3. The future of web development4. Why I switched from React to Vue5. Building scalable microservices with Goโ Automation completed successfully!๐งน Resources cleaned up
Complete Example
Here's the complete script that puts all steps together:
1/*2* AI-powered browser automation using Stagehand with Steel browsers.3*/45import { Stagehand } from "@browserbasehq/stagehand";6import Steel from "steel-sdk";7import { z } from "zod";8import dotenv from "dotenv";910// Load environment variables11dotenv.config();1213const STEEL_API_KEY = process.env.STEEL_API_KEY;14const OPENAI_API_KEY = process.env.OPENAI_API_KEY;1516// Define data schemas for structured extraction17const StorySchema = z.object({18title: z.string(),19rank: z.number()20});2122const StoriesSchema = z.object({23stories: z.array(StorySchema)24});2526async function main() {27console.log("๐ Steel + Stagehand Automation");28console.log("=".repeat(50));2930let session: any = null;31let stagehand: Stagehand | null = null;3233try {34// Initialize Steel client and create session35const client = new Steel({36steelAPIKey: STEEL_API_KEY,37});3839session = await client.sessions.create();4041console.log("โ Steel browser session created!");42console.log(`View live session at: ${session.sessionViewerUrl}`);4344// Configure and initialize Stagehand45stagehand = new Stagehand({46env: "LOCAL",47localBrowserLaunchOptions: {48cdpUrl: `${session.websocketUrl}&apiKey=${STEEL_API_KEY}`,49},50enableCaching: false,51modelClientOptions: {52apiKey: OPENAI_API_KEY,53},54});5556console.log("๐ค Initializing Stagehand...");57await stagehand.init();58console.log("Connected to Steel browser via Stagehand");5960// Navigate and extract data61console.log("๐ฐ Navigating to Hacker News...");62await stagehand.page.goto("https://news.ycombinator.com");6364console.log("๐ Extracting top stories...");65const stories = await stagehand.page.extract({66instruction: "extract the titles and ranks of the first 5 stories on the page",67schema: StoriesSchema,68});6970console.log("\n๐ Top 5 Hacker News Stories:");71stories.stories.forEach((story, index) => {72console.log(`${story.rank}. ${story.title}`);73});7475console.log("\nโ Automation completed successfully!");7677} catch (error) {78console.error("โ Error during automation:", error);7980} finally {81// Clean up resources82if (stagehand) {83await stagehand.close();84}85if (session) {86const client = new Steel({ steelAPIKey: STEEL_API_KEY });87await client.sessions.release(session.id);88}89console.log("๐งน Resources cleaned up");90}91}9293// Run the automation94main().catch((error) => {95console.error("Unhandled error:", error);96process.exit(1);97});98
Advanced Usage Examples
Custom Data Extraction Schema
1const ProductSchema = z.object({2products: z.array(3z.object({4name: z.string(),5price: z.string(),6rating: z.number().optional(),7inStock: z.boolean(),8})9),10});1112const productData = await stagehand.page.extract({13instruction: "extract product information from this e-commerce page",14schema: ProductSchema,15});16
Complex Actions with Natural Language
1// Fill out a form using natural language2await stagehand.page.act(3"fill out the contact form with name 'John Doe', email 'john@example.com', and message 'Hello!'"4);56// Navigate through multi-step processes7await stagehand.page.act(8"click on the 'Sign Up' button and then fill out the registration form"9);1011// Handle dynamic content12await stagehand.page.act(13"wait for the page to load completely, then click on the first product"14);15
Next Steps
Now that you have a working Stagehand + Steel automation, try these enhancements:
-
Custom data extraction: Create your own Zod schemas for different websites
-
Complex interactions: Use
stagehand.page.act()
for clicking, typing, and navigation -
Multiple pages: Navigate through multi-step workflows
-
Error handling: Add retry logic and better error management
For more advanced features, check out:
-
Stagehand documentation for natural language automation
-
Steel API documentation for session management options
-
Steel GitHub examples for more integration patterns