Skip to main content

Overview

The Stagehand + Next.js Quickstart is a production-ready template that pairs Stagehand’s AI browser automation with a modern Next.js app, deployable in one click on Vercel.

Deploy Template

One-click deploy to Vercel with environment setup

Live Demo

See the deployed template in action

Source Code

Browse the repository on GitHub

What You Get

App Router Project

Next.js App Router scaffold with Tailwind styling

Server-Safe Automation

Uses Browserbase for cloud browsers (works on Vercel functions)

Pre-wired Config

stagehand.config.ts with model and provider switching

Automation Ready

Example usage of Stagehand primitives

Requirements

  • Node 18+ locally
  • Model key: OpenAI or Anthropic (or plug a custom client)
  • Browserbase keys: BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID for cloud browsers
Local Playwright browsers are not available on Vercel. Set Stagehand to use Browserbase when deploying.

Quick Start

1. Deploy to Vercel

Click the deploy button to create a new project:

Deploy to Vercel

One-click deployment
During deployment, you’ll be prompted to add environment variables:
BROWSERBASE_API_KEY=your_browserbase_api_key
BROWSERBASE_PROJECT_ID=your_browserbase_project_id
OPENAI_API_KEY=your_openai_api_key

2. Local Development

Clone your deployed repository and run locally:
# Clone your repository
git clone https://github.com/your-username/your-project-name
cd your-project-name

# Install dependencies
npm install

# Copy environment variables
cp .env.example .env.local

# Add your keys to .env.local
# Then run the development server
npm run dev
Open http://localhost:3000 to see your app.

Project Structure

my-stagehand-app/
├── app/
│   ├── api/
│   │   └── automate/
│   │       └── route.ts        # API route for Stagehand
│   ├── layout.tsx
│   └── page.tsx
├── lib/
│   └── stagehand.config.ts     # Stagehand configuration
├── .env.local                   # Environment variables
└── package.json

Configuration

Stagehand Config

Create or edit lib/stagehand.config.ts:
import { Stagehand } from "@browserbasehq/stagehand";

export const getStagehand = () => {
  return new Stagehand({
    env: "BROWSERBASE",
    verbose: 1,
    debugDom: true,
    enableCaching: true,
  });
};

Environment Variables

Add to .env.local for local development:
# Required for Browserbase
BROWSERBASE_API_KEY=your_browserbase_api_key
BROWSERBASE_PROJECT_ID=your_browserbase_project_id

# Required for LLM
OPENAI_API_KEY=your_openai_api_key
# Or use Anthropic
# ANTHROPIC_API_KEY=your_anthropic_api_key
Add the same variables to your Vercel project settings:
  1. Go to your project on Vercel
  2. Navigate to Settings → Environment Variables
  3. Add each variable for Production, Preview, and Development

API Route Example

Create an API route at app/api/automate/route.ts:
import { NextRequest, NextResponse } from "next/server";
import { Stagehand } from "@browserbasehq/stagehand";
import { z } from "zod";

export async function POST(request: NextRequest) {
  try {
    const { url, action } = await request.json();

    const stagehand = new Stagehand({
      env: "BROWSERBASE",
      verbose: 1,
    });

    await stagehand.init();

    const page = stagehand.context.pages()[0];
    await page.goto(url);

    // Perform action
    await stagehand.act(action);

    // Extract data
    const data = await stagehand.extract(
      "extract the page title and main content",
      z.object({
        title: z.string(),
        content: z.string(),
      })
    );

    await stagehand.close();

    return NextResponse.json({ success: true, data });
  } catch (error) {
    console.error("Automation error:", error);
    return NextResponse.json(
      { success: false, error: "Automation failed" },
      { status: 500 }
    );
  }
}

Frontend Integration

Use the API route from your frontend:
"use client";

import { useState } from "react";

export default function Home() {
  const [result, setResult] = useState(null);
  const [loading, setLoading] = useState(false);

  const handleAutomation = async () => {
    setLoading(true);
    
    try {
      const response = await fetch("/api/automate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          url: "https://example.com",
          action: "click the login button",
        }),
      });

      const data = await response.json();
      setResult(data);
    } catch (error) {
      console.error("Error:", error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold mb-4">Stagehand Automation</h1>
      <button
        onClick={handleAutomation}
        disabled={loading}
        className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
      >
        {loading ? "Running..." : "Start Automation"}
      </button>
      
      {result && (
        <pre className="mt-4 p-4 bg-gray-100 rounded">
          {JSON.stringify(result, null, 2)}
        </pre>
      )}
    </div>
  );
}

Advanced: Using Different Models

OpenAI

import { Stagehand } from "@browserbasehq/stagehand";

const stagehand = new Stagehand({
  env: "BROWSERBASE",
  model: "openai/gpt-4o",
});

Anthropic Claude

import { Stagehand } from "@browserbasehq/stagehand";

const stagehand = new Stagehand({
  env: "BROWSERBASE",
  model: "anthropic/claude-sonnet-4-5",
});

Custom LLM Client

Use the AI SDK for custom models:
import { Stagehand, AISdkClient } from "@browserbasehq/stagehand";
import { openai } from "@ai-sdk/openai";

const customModel = openai("gpt-4-turbo");

const stagehand = new Stagehand({
  env: "BROWSERBASE",
  llmClient: new AISdkClient({ model: customModel }),
});

Deployment Checklist

1

Environment Variables

Add all required environment variables to Vercel:
  • BROWSERBASE_API_KEY
  • BROWSERBASE_PROJECT_ID
  • OPENAI_API_KEY or ANTHROPIC_API_KEY
2

Verify Configuration

Ensure stagehand.config.ts uses env: "BROWSERBASE"
3

Test Locally

Run npm run dev and test all automation flows
4

Deploy

Push to your repository or click deploy on Vercel
5

Monitor

Check the Browserbase Dashboard for session activity

Troubleshooting

”Browser not found” Error

Make sure you’re using env: "BROWSERBASE" instead of env: "LOCAL":
const stagehand = new Stagehand({
  env: "BROWSERBASE", // Not "LOCAL"
});

API Route Timeout

Increase the serverless function timeout in vercel.json:
{
  "functions": {
    "app/api/**/*.ts": {
      "maxDuration": 60
    }
  }
}

Environment Variables Not Loading

Ensure variables are added to all environments in Vercel:
  • Production
  • Preview
  • Development

Performance Tips

  1. Enable Caching: Set enableCaching: true in Stagehand config
  2. Reuse Instances: Create Stagehand instances once and reuse when possible
  3. Use Contexts: Leverage Browserbase contexts for persistent sessions
  4. Optimize Timeouts: Adjust domSettleTimeoutMs based on your needs

Example Use Cases

Web Scraping API

Build an API endpoint that extracts data from any website

Automated Testing

Create E2E tests for your application

Form Automation

Automate form filling and submission

Data Monitoring

Monitor competitors or track price changes

Resources

Vercel Documentation

Learn about Vercel deployment

Next.js Documentation

Next.js App Router guides

Browserbase Dashboard

Monitor your browser sessions

Stagehand API

Explore Stagehand’s capabilities

Template Repository

View the source code

Support

Get help from our team

Build docs developers (and LLMs) love