npx skills add ...
npx skills add browserbase/browse-plugin --skill functions
npx skills add browserbase/browse-plugin --skill functions
Guide deployment of serverless browser automation using the official Browserbase Functions CLI. Use when the user wants to deploy automation to run on a schedule, needs a webhook endpoint for browser automation, wants to run automation in the cloud, or asks about Browserbase Functions.
Deploy serverless browser automation to the cloud using the official bb CLI.
Get API key and Project ID from: https://browserbase.com/settings
This creates:
Key objects:
context.session.connectUrl -- CDP endpoint to connect Playwrightcontext.params -- Input parameters from invocationServer runs at http://127.0.0.1:14113
The dev server auto-reloads on file changes.
Save the Function ID from the output -- you need it to invoke.
| Command | Description |
|---|---|
pnpm dlx @browserbasehq/sdk-functions init <name> | Create new project |
pnpm bb dev <file> | Start local dev server |
pnpm bb publish <file> | Deploy to Browserbase |
waitForSelector instead of sleepsession.connectUrl is being used correctlychromium.connectOverCDP() not chromium.launch()
$$echo "BROWSERBASE_API_KEY=$BROWSERBASE_API_KEY" >> .env
echo "BROWSERBASE_PROJECT_ID=$BROWSERBASE_PROJECT_ID" >> .envpnpm installimport { defineFn } from "@browserbasehq/sdk-functions";
import { chromium } from "playwright-core";
defineFn("my-function", async (context) => {
const { session, params } = context;
// Connect to browser
const browser = await chromium.connectOverCDP(session.connectUrl);
const page = browser.contexts()[0]!.pages()[0]!;
// Your automation
await page.goto(params.url || "https://example.com");
const title = await page.title();
// Return JSON-serializable result
return { success: true, title };
});pnpm bb dev index.tscurl -X POST http://127.0.0.1:14113/v1/functions/my-function/invoke \
-H "Content-Type: application/json" \
-d '{"params": {"url": "https://news.ycombinator.com"}}'pnpm bb publish index.ts# Start invocation
curl -X POST "https://api.browserbase.com/v1/functions/FUNCTION_ID/invoke" \
-H "Content-Type: application/json" \
-H "x-bb-api-key: $BROWSERBASE_API_KEY" \
-d '{"params": {"url": "https://example.com"}}'
# Response: {"id": "INVOCATION_ID"}
# Poll for result
curl "https://api.browserbase.com/v1/functions/invocations/INVOCATION_ID" \
-H "x-bb-api-key: $BROWSERBASE_API_KEY"async function invokeFunction(functionId: string, params: object) {
const invokeRes = await fetch(
`https://api.browserbase.com/v1/functions/${functionId}/invoke`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-bb-api-key': process.env.BROWSERBASE_API_KEY!,
},
body: JSON.stringify({ params }),
}
);
const { id: invocationId } = await invokeRes.json();
while (true) {
await new Promise(r => setTimeout(r, 5000));
const statusRes = await fetch(
`https://api.browserbase.com/v1/functions/invocations/${invocationId}`,
{ headers: { 'x-bb-api-key': process.env.BROWSERBASE_API_KEY! } }
);
const result = await statusRes.json();
if (result.status === 'COMPLETED') return result.results;
if (result.status === 'FAILED') throw new Error(result.error);
}
}defineFn("scrape", async ({ session, params }) => {
const browser = await chromium.connectOverCDP(session.connectUrl);
const page = browser.contexts()[0]!.pages()[0]!;
await page.goto(params.url);
await page.waitForSelector(params.selector);
const items = await page.$$eval(params.selector, els =>
els.map(el => el.textContent?.trim())
);
return { url: params.url, items };
});defineFn("authenticated-action", async ({ session, params }) => {
const browser = await chromium.connectOverCDP(session.connectUrl);
const page = browser.contexts()[0]!.pages()[0]!;
await page.goto("https://example.com/login");
await page.fill('[name="email"]', params.email);
await page.fill('[name="password"]', params.password);
await page.click('button[type="submit"]');
await page.waitForURL('**/dashboard');
const data = await page.textContent('.user-data');
return { data };
});defineFn("safe-scrape", async ({ session, params }) => {
const browser = await chromium.connectOverCDP(session.connectUrl);
const page = browser.contexts()[0]!.pages()[0]!;
try {
await page.goto(params.url, { timeout: 30000 });
await page.waitForSelector(params.selector, { timeout: 10000 });
const data = await page.textContent(params.selector);
return { success: true, data };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
});cat .env # Check credentials exist
export BROWSERBASE_API_KEY="your_key"
export BROWSERBASE_PROJECT_ID="your_project"pnpm add @browserbasehq/sdk-functions