Automação de Navegador com Vercel Sandbox
Execute agente-browser + Chrome headless dentro de microVMs Vercel Sandbox efêmeras. Uma VM Linux é iniciada sob demanda, executa comandos do navegador e é encerrada. Funciona com qualquer framework implantado na Vercel (Next.js, SvelteKit, Nuxt, Remix, Astro, etc.).
Dependências
pnpm add @agent-browser/sandbox @vercel/sandbox
A VM sandbox precisa de dependências de sistema para Chromium além do próprio agente-browser. Os helpers @agent-browser/sandbox instalam-nas por padrão para novas sandboxes e usam sandbox snapshots (abaixo) para inicialização em menos de um segundo. Passe installSystemDependencies: false apenas quando a imagem da sandbox já fornecer as bibliotecas necessárias do Chromium.
Padrão Central
import {
createAgentBrowserSnapshot,
runAgentBrowserCommand,
withAgentBrowserSandbox,
type VercelSandboxSession,
} from "@agent-browser/sandbox/vercel";
async function withBrowser<T>(
fn: (sandbox: VercelSandboxSession) => Promise<T>,
): Promise<T> {
return withAgentBrowserSandbox(fn);
}
Screenshot
O comando screenshot --json salva em um arquivo e retorna o caminho. Leia o arquivo de volta como base64:
export async function screenshotUrl(url: string) {
return withBrowser(async (sandbox) => {
await runAgentBrowserCommand(sandbox, ["open", url]);
const titleResult = await runAgentBrowserCommand<{ data?: { title?: string } }>(sandbox, [
"get", "title",
]);
const title = titleResult.json?.data?.title || url;
const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
"screenshot",
]);
const ssPath = ssResult.json?.data?.path;
if (!ssPath) throw new Error("Screenshot não retornou um caminho de arquivo.");
const b64Result = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
const screenshot = (await b64Result.stdout()).trim();
await runAgentBrowserCommand(sandbox, ["close"], { json: false });
return { title, screenshot };
});
}
Snapshot de Acessibilidade
export async function snapshotUrl(url: string) {
return withBrowser(async (sandbox) => {
await runAgentBrowserCommand(sandbox, ["open", url]);
const titleResult = await runAgentBrowserCommand<{ data?: { title?: string } }>(sandbox, [
"get", "title",
]);
const title = titleResult.json?.data?.title || url;
const snapResult = await runAgentBrowserCommand(sandbox, ["snapshot", "-i", "-c"], {
json: false,
});
await runAgentBrowserCommand(sandbox, ["close"], { json: false });
return { title, snapshot: snapResult.stdout };
});
}
Fluxos de Trabalho com Múltiplas Etapas
A sandbox persiste entre comandos, permitindo executar sequências completas de automação:
export async function fillAndSubmitForm(
url: string,
data: Record<string, string>,
postSubmitWaitArgs: string[],
) {
return withBrowser(async (sandbox) => {
await runAgentBrowserCommand(sandbox, ["open", url]);
const snapResult = await runAgentBrowserCommand(sandbox, ["snapshot", "-i"], {
json: false,
});
const snapshot = snapResult.stdout;
// Analisa o snapshot para encontrar referências de elementos...
for (const [ref, value] of Object.entries(data)) {
await runAgentBrowserCommand(sandbox, ["fill", ref, value]);
}
await runAgentBrowserCommand(sandbox, ["click", "@e5"]);
// Passe uma espera específica do aplicativo, como ["--url", "**/checkout/complete"],
// ["--text", "Obrigado"] ou ["#confirmation"].
await runAgentBrowserCommand(sandbox, ["wait", ...postSubmitWaitArgs]);
const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
"screenshot",
]);
const ssPath = ssResult.json?.data?.path;
if (!ssPath) throw new Error("Screenshot não retornou um caminho de arquivo.");
const b64Result = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
const screenshot = (await b64Result.stdout()).trim();
await runAgentBrowserCommand(sandbox, ["close"], { json: false });
return { screenshot };
});
}
Snapshots de Sandbox (Inicialização Rápida)
Um sandbox snapshot é uma imagem de VM salva de um Vercel Sandbox com dependências de sistema + agente-browser + Chromium já instalados. Pense nisso como uma imagem Docker: em vez de instalar dependências do zero toda vez, a sandbox é iniciada a partir da imagem pré-construída.
Isso não está relacionado ao recurso de snapshot de acessibilidade do agente-browser (agent-browser snapshot), que despeja a árvore de acessibilidade de uma página. Um sandbox snapshot é um conceito de infraestrutura da Vercel para inicialização rápida de VMs.
Sem um sandbox snapshot, cada execução instala deps do sistema + agente-browser + Chromium (~30s). Com um, a inicialização leva menos de um segundo.
Criando um sandbox snapshot
O snapshot deve incluir dependências de sistema (via dnf), agente-browser e Chromium:
const snapshotId = await createAgentBrowserSnapshot();
Execute isso uma vez e depois defina a variável de ambiente:
AGENT_BROWSER_SNAPSHOT_ID=snap_xxxxxxxxxxxx
Um script auxiliar está disponível no aplicativo de demonstração:
npx tsx examples/environments/scripts/create-snapshot.ts
Recomendado para qualquer implantação em produção que use o padrão Sandbox.
Autenticação
Em implantações na Vercel, o Sandbox SDK autentica automaticamente via OIDC. Para desenvolvimento local ou controle explícito, defina:
VERCEL_TOKEN=<token-de-acesso-pessoal>
VERCEL_TEAM_ID=<id-do-time>
VERCEL_PROJECT_ID=<id-do-projeto>
Esses são espalhados nas chamadas Sandbox.create(). Quando ausentes, o SDK usa VERCEL_OIDC_TOKEN como fallback (automático na Vercel).
Fluxos de Trabalho Agendados (Cron)
Combine com Cron Jobs da Vercel para tarefas recorrentes de navegador:
// app/api/cron/route.ts (ou equivalente no seu framework)
export async function GET() {
const result = await withBrowser(async (sandbox) => {
await sandbox.runCommand("agent-browser", ["open", "https://example.com/pricing"]);
const snap = await sandbox.runCommand("agent-browser", ["snapshot", "-i", "-c"]);
await sandbox.runCommand("agent-browser", ["close"]);
return await snap.stdout();
});
// Processar resultados, enviar alertas, armazenar dados...
return Response.json({ ok: true, snapshot: result });
}
// vercel.json
{ "crons": [{ "path": "/api/cron", "schedule": "0 9 * * *" }] }
Variáveis de Ambiente
| Variável | Obrigatório | Descrição |
|---|---|---|
AGENT_BROWSER_SNAPSHOT_ID | Não (mas recomendado) | ID do snapshot de sandbox pré-construído para inicialização em menos de um segundo (veja acima) |
VERCEL_TOKEN | Não | Token de acesso pessoal da Vercel (para desenvolvimento local; OIDC é automático na Vercel) |
VERCEL_TEAM_ID | Não | ID do time da Vercel (para desenvolvimento local) |
VERCEL_PROJECT_ID | Não | ID do projeto da Vercel (para desenvolvimento local) |
Exemplos por Framework
O padrão funciona de forma idêntica em todos os frameworks. A única diferença é onde colocar o código do lado do servidor:
| Framework | Localização do código do servidor |
|---|---|
| Next.js | Server actions, rotas de API, manipuladores de rota |
| SvelteKit | +page.server.ts, +server.ts |
| Nuxt | server/api/, server/routes/ |
| Remix | Funções loader, action |
| Astro | Frontmatter .astro, rotas de API |
Exemplo
Veja examples/environments/ no repositório agent-browser para um aplicativo funcional com o padrão Vercel Sandbox, incluindo um script de criação de sandbox snapshot, UI de progresso com streaming e limitação de taxa.