Stagehand
Stagehand ↗ is ___
You can use Stagehand to ___
After you deploy, you can interact with the Worker using this URL pattern:
https://<your-worker>.workers.devIn this example, you will search for a movie on https://www.themoviedb.org/ ↗ and return the movie's title, year, and director, as well as a screenshot of the webpage.
If you want to skip the steps and get started quickly, select Deploy to Cloudflare below.
-
Install dependencies:
Terminal window npm ci -
Make sure you have the browser rendering in your wrangler configuration file:
{"name": "cloudflare-stagehand-example","main": "src/index.ts","compatibility_flags": ["nodejs_compat", "enable_nodejs_fs_module"],"compatibility_date": "2025-09-01","workers_dev": true,"upload_source_maps": true,"alias": {"playwright": "@cloudflare/playwright"},"observability": {"enabled": true},"browser": {"binding": "BROWSER","experimental_remote": true},"ai": {"binding": "AI"}}name = "cloudflare-stagehand-example"main = "src/index.ts"compatibility_flags = [ "nodejs_compat", "enable_nodejs_fs_module" ]compatibility_date = "2025-09-01"workers_dev = trueupload_source_maps = true[alias]playwright = "@cloudflare/playwright"[observability]enabled = true[browser]binding = "BROWSER"experimental_remote = true[ai]binding = "AI" -
Edit the code:
src/index.ts import { Stagehand } from "@browserbasehq/stagehand";import { z } from "zod";import { endpointURLString } from "@cloudflare/playwright";import { createWorkersAI } from "workers-ai-provider";import { AISdkClient } from "./aidsk";export default {async fetch(request: Request, env: Env) {const url = new URL(request.url);if (url.pathname !== "/")return new Response("Not found", { status: 404 });const workersai = createWorkersAI({ binding: env.AI });// @ts-ignoreconst model = workersai("@cf/meta/llama-3.3-70b-instruct-fp8-fast");const stagehand = new Stagehand({env: "LOCAL",localBrowserLaunchOptions: { cdpUrl: endpointURLString("BROWSER") },llmClient: new AISdkClient({ model }),verbose: 1,});await stagehand.init();const page = stagehand.page;await page.goto('https://www.themoviedb.org/');// for multi-step actions, use observeconst actions = await page.observe('Search for "The Iron Giant" and click the Search button');for (const action of actions)await page.act(action);await page.act('Click the first search result');let movieInfo = await page.extract({instruction: 'Extract movie information',schema: z.object({title: z.string(),year: z.number(),director: z.string(),}),});const screenshot = await page.screenshot();await stagehand.close();return new Response(`<html><head><title>Cloudflare Stagehand Example</title><style>body {font-family: system-ui, -apple-system, sans-serif;}</style></head><body><h1>Stagehand Example</h1><p>This example shows how to use <a href="https://www.stagehand.dev/">stagehand</a> to extract information from a web page.</p><h2>Movie Information</h2><div><p><b>Title:</b> ${movieInfo.title}</p><p><b>Release Year:</b> ${movieInfo.year}</p><p><b>Director:</b> ${movieInfo.director}</p></div><img src="data:image/png;base64,${screenshot.toString('base64')}" /></body></html>`, {headers: {"Content-Type": "text/html; charset=utf-8",},});},}; -
Build the project:
Terminal window npm run build -
Deploy to Cloudflare Workers:
Terminal window npm run deploy
Instead of using a model from Workers AI, you can use a custom model for which you supply your own credentials.
In this example, you will configure Stagehand to use OpenAI ↗. You will need an OpenAI API key. Cloudflare recommends storing your API key with secrets.
const stagehand = new Stagehand({ env: "LOCAL", localBrowserLaunchOptions: { cdpUrl: endpointURLString("BROWSER") }, modelName: "openai/gpt-4.1", modelClientOptions: { apiKey: env.OPENAI_API_KEY, },});const stagehand = new Stagehand({ env: "LOCAL", localBrowserLaunchOptions: { cdpUrl: endpointURLString("BROWSER") }, modelName: "openai/gpt-4.1", modelClientOptions: { apiKey: env.OPENAI_API_KEY, baseURL: `https://gateway.ai.cloudflare.com/v1/${env.CLOUDFLARE_ACCOUNT_ID}/${env.AI_GATEWAY_ID}/openai`, },});Was this helpful?
- Resources
- API
- New to Cloudflare?
- Directory
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- © 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark