Next.js + Vercel#
Run agent-browser from a Next.js app on Vercel using Vercel Sandbox. A Linux microVM spins up on demand, runs agent-browser + Chrome, and shuts down. No binary size limits, no Chromium bundling complexity.
Setup#
pnpm add @agent-browser/sandbox @vercel/sandboxServer action#
The Vercel Sandbox runs Amazon Linux. Chromium requires system libraries that are not installed by default, so fresh sandboxes need a dnf install step before agent-browser can launch Chrome. Use a sandbox snapshot (below) to skip this entirely in production. The @agent-browser/sandbox helper installs those system dependencies by default and handles command execution.
"use server";
import { runAgentBrowserCommand, withAgentBrowserSandbox } from "@agent-browser/sandbox/vercel";
export async function screenshotUrl(url: string) {
return withAgentBrowserSandbox(async (sandbox) => {
await runAgentBrowserCommand(sandbox, ["open", url]);
const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
"screenshot",
]);
const ssPath = ssResult.json?.data?.path;
if (!ssPath) throw new Error("Screenshot did not return a file path.");
const b64Result = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
const screenshot = (await b64Result.stdout()).trim();
await runAgentBrowserCommand(sandbox, ["close"], { json: false });
return { ok: true, screenshot };
});
}
export async function snapshotUrl(url: string) {
return withAgentBrowserSandbox(async (sandbox) => {
await runAgentBrowserCommand(sandbox, ["open", url]);
const result = await runAgentBrowserCommand(sandbox, ["snapshot", "-i", "-c"], {
json: false,
});
await runAgentBrowserCommand(sandbox, ["close"], { json: false });
return { ok: true, snapshot: result.stdout };
});
}Sandbox snapshots#
Without optimization, each Sandbox run installs system dependencies + agent-browser + Chromium from scratch (~30 seconds). A sandbox snapshot is a saved VM image with everything pre-installed, similar to a Docker image for Vercel Sandbox. When AGENT_BROWSER_SNAPSHOT_ID is set, the sandbox boots from that image instead of installing, bringing startup down to sub-second.
This is different from an agent-browser accessibility snapshot (which dumps a page's accessibility tree). A sandbox snapshot is a Vercel infrastructure concept.
Create a sandbox snapshot by running the helper script once:
npx tsx scripts/create-snapshot.tsThe script spins up a fresh sandbox, installs system dependencies + agent-browser + Chromium, saves the VM state, and prints the snapshot ID:
AGENT_BROWSER_SNAPSHOT_ID=snap_xxxxxxxxxxxxAdd this to your Vercel project environment variables (or .env.local for local development). Recommended for any production deployment.
Authentication#
On Vercel deployments, the Sandbox SDK authenticates automatically via OIDC. For local development, provide explicit credentials:
| Variable | Description |
|---|---|
VERCEL_TOKEN | Vercel personal access token |
VERCEL_TEAM_ID | Vercel team ID |
VERCEL_PROJECT_ID | Vercel project ID |
When all three are set, they are passed to Sandbox.create(). When absent, the SDK falls back to VERCEL_OIDC_TOKEN (automatic on Vercel).
Scheduled workflows (cron)#
For recurring tasks like daily monitoring, use Vercel Cron Jobs:
// app/api/cron/monitor/route.ts
import { runAgentBrowserCommand, withAgentBrowserSandbox } from "@agent-browser/sandbox/vercel";
export async function GET() {
const result = await withAgentBrowserSandbox(async (sandbox) => {
await runAgentBrowserCommand(sandbox, [
"open", "https://example.com/pricing",
]);
const snap = await runAgentBrowserCommand(sandbox, [
"snapshot", "-i", "-c",
], { json: false });
await runAgentBrowserCommand(sandbox, ["close"], { json: false });
return snap.stdout;
});
// Process results, send alerts, store data...
return Response.json({ ok: true, snapshot: result });
}// vercel.json
{
"crons": [
{ "path": "/api/cron/monitor", "schedule": "0 9 * * *" }
]
}Environment variables#
| Variable | Description |
|---|---|
AGENT_BROWSER_SNAPSHOT_ID | Sandbox snapshot ID for sub-second startup (see above) |
VERCEL_TOKEN | Vercel personal access token (for local dev; OIDC is automatic on Vercel) |
VERCEL_TEAM_ID | Vercel team ID (for local dev) |
VERCEL_PROJECT_ID | Vercel project ID (for local dev) |
Demo app#
A working demo with streaming progress UI, rate limiting, and a deploy-to-Vercel button is at examples/environments/.