browse

Browser Automation & Functions Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "browse" with this command: npx skills add browserbase/skills/browserbase-skills-browse

Browser Automation & Functions Skill

Complete guide for creating and deploying browser automation functions using the browse CLI.

Installation

npm install -g @browserbasehq/browse-cli

Requires Chrome/Chromium installed on the system.

When to Use

  • User wants to automate a website task

  • User needs to scrape data from a site

  • User wants to create a Browserbase Function

  • User wants to deploy automation to run on a schedule or via webhook

Prerequisites

Set Up Credentials

Get API key and Project ID from: https://browserbase.com/settings

export BROWSERBASE_API_KEY="your_api_key" export BROWSERBASE_PROJECT_ID="your_project_id"

Complete Workflow

Step 1: Explore the Site Interactively

Start a browser session to understand the site structure:

browse open https://example.com browse snapshot # Get DOM structure with refs browse screenshot page.png # Visual inspection

Test interactions manually:

browse click @0-5 browse fill @0-6 "value" browse stop # When done exploring

Step 2: Initialize Function Project

pnpm dlx @browserbasehq/sdk-functions init my-automation cd my-automation

Creates:

  • package.json

  • Dependencies

  • .env

  • Add credentials here

  • index.ts

  • Function template

  • tsconfig.json

  • TypeScript config

Step 3: ⚠️ FIX package.json IMMEDIATELY

CRITICAL BUG: The init command may generate incomplete package.json that causes deployment to fail with "No functions were built."

REQUIRED FIX - Update package.json before doing anything else:

{ "name": "my-automation", "version": "1.0.0", "description": "My automation description", "main": "index.js", "type": "module", "packageManager": "pnpm@10.14.0", "scripts": { "dev": "pnpm bb dev index.ts", "publish": "pnpm bb publish index.ts" }, "dependencies": { "@browserbasehq/sdk-functions": "^0.0.5", "playwright-core": "^1.58.0" }, "devDependencies": { "@types/node": "^25.0.10", "typescript": "^5.9.3" } }

Key changes from generated file:

  • ✅ Add description and main fields

  • ✅ Add packageManager field

  • ✅ Change "latest" to pinned versions like "^0.0.5"

  • ✅ Add devDependencies with TypeScript and types

Then install:

pnpm install

Step 4: Write Automation Code

Edit index.ts :

import { defineFn } from "@browserbasehq/sdk-functions"; import { chromium } from "playwright-core";

defineFn("my-automation", async (context) => { const { session, params } = context; console.log("Connecting to browser session:", session.id);

const browser = await chromium.connectOverCDP(session.connectUrl); const page = browser.contexts()[0]!.pages()[0]!;

// Your automation here await page.goto("https://example.com"); await page.waitForLoadState("domcontentloaded");

// Extract data const data = await page.evaluate(() => { // Complex extraction logic return Array.from(document.querySelectorAll('.item')).map(el => ({ title: el.querySelector('.title')?.textContent, value: el.querySelector('.value')?.textContent, })); });

// Return results (must be JSON-serializable) return { success: true, count: data.length, data, timestamp: new Date().toISOString(), }; });

Key Concepts:

  • context.session

  • Browser session info (id, connectUrl)

  • context.params

  • Input parameters from invocation

  • Return JSON-serializable data

  • 15 minute max execution time

Step 5: Test Locally

Start dev server:

pnpm bb dev index.ts

Server runs at http://127.0.0.1:14113

Invoke with curl:

curl -X POST http://127.0.0.1:14113/v1/functions/my-automation/invoke
-H "Content-Type: application/json"
-d '{"params": {"url": "https://example.com"}}'

Dev server auto-reloads on file changes. Check terminal for logs.

Step 6: Deploy to Browserbase

pnpm bb publish index.ts

Expected output:

✓ Build completed successfully Build ID: xxx-xxx-xxx Function ID: yyy-yyy-yyy ← Save this!

If you see "No functions were built" → Your package.json is incomplete (see Step 3).

Step 7: Test Production

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": {}}'

Complete Working Example: Hacker News Scraper

import { defineFn } from "@browserbasehq/sdk-functions"; import { chromium } from "playwright-core";

defineFn("hn-scraper", async (context) => { const { session } = context; console.log("Connecting to browser session:", session.id);

const browser = await chromium.connectOverCDP(session.connectUrl); const page = browser.contexts()[0]!.pages()[0]!;

await page.goto("https://news.ycombinator.com"); await page.waitForLoadState("domcontentloaded");

// Extract top 10 stories const stories = await page.evaluate(() => { const storyRows = Array.from(document.querySelectorAll('.athing')).slice(0, 10);

return storyRows.map((row) => {
  const titleLine = row.querySelector('.titleline a');
  const subtext = row.nextElementSibling?.querySelector('.subtext');
  const commentsLink = Array.from(subtext?.querySelectorAll('a') || []).pop();

  return {
    rank: row.querySelector('.rank')?.textContent?.replace('.', '') || '',
    title: titleLine?.textContent || '',
    url: titleLine?.getAttribute('href') || '',
    points: subtext?.querySelector('.score')?.textContent?.replace(' points', '') || '0',
    author: subtext?.querySelector('.hnuser')?.textContent || '',
    time: subtext?.querySelector('.age')?.textContent || '',
    comments: commentsLink?.textContent?.replace(/\u00a0comments?/, '').trim() || '0',
    id: row.id,
  };
});

});

return { success: true, count: stories.length, stories, timestamp: new Date().toISOString(), }; });

Common Patterns

Parameterized Scraping

defineFn("scrape", async (context) => { const { session, params } = context; const { url, selector } = params; // Accept params from invocation

const browser = await chromium.connectOverCDP(session.connectUrl); const page = browser.contexts()[0]!.pages()[0]!;

await page.goto(url); const data = await page.$$eval(selector, els => els.map(el => el.textContent) );

return { url, data }; });

Authentication

defineFn("auth-action", async (context) => { const { session, params } = context; const { username, password } = 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('input[name="email"]', username); await page.fill('input[name="password"]', password); await page.click('button[type="submit"]'); await page.waitForURL("**/dashboard");

const data = await page.textContent('.user-data'); return { success: true, data }; });

Multi-Page Workflow

defineFn("multi-page", async (context) => { const { session, params } = context; const browser = await chromium.connectOverCDP(session.connectUrl); const page = browser.contexts()[0]!.pages()[0]!;

const results = []; for (const url of params.urls) { await page.goto(url); await page.waitForLoadState("domcontentloaded");

const title = await page.title();
results.push({ url, title });

}

return { results }; });

Troubleshooting

🔴 "No functions were built. Please check your entrypoint and function exports."

This is the #1 error!

Cause: Generated package.json is incomplete.

Fix:

  • Update package.json (see Step 3 above)

  • Add all required fields: description , main , packageManager

  • Change "latest" to pinned versions like "^0.0.5"

  • Add devDependencies section with TypeScript and types

  • Run pnpm install

  • Try deploying again

Quick check: Compare your package.json to bitcoin-functions/package.json in the codebase.

Local dev server won't start

Check credentials in .env

cat .env

Install SDK globally

pnpm add -g @browserbasehq/sdk-functions

Function works locally but fails on deploy

Common causes:

  • Missing devDependencies (TypeScript won't compile)

  • Using "latest" instead of pinned versions

  • Missing required fields in package.json

Solution: Fix package.json as described in Step 3.

Cannot extract data from page

  • Take screenshot: browse screenshot debug.png

  • Get snapshot: browse snapshot

  • Use page.evaluate() to log what's in the DOM

  • Check if selectors match actual HTML structure

"Invocation timed out"

  • Functions have 15 minute max

  • Use specific waits instead of long sleeps

  • Check if page is actually loading

Best Practices

  • ✅ Fix package.json immediately after init

  • ✅ Explore interactively first - Use browser session to understand site

  • ✅ Test manually - Verify each step works before writing code

  • ✅ Test locally - Use dev server before deploying

  • ✅ Return meaningful data - Include timestamps, counts, URLs

  • ✅ Handle errors gracefully - Try/catch around risky operations

  • ✅ Use specific selectors - Prefer data attributes over CSS classes

  • ✅ Add logging - console.log() helps debug deployed functions

  • ✅ Validate parameters - Check params before using

  • ✅ Set reasonable timeouts - Don't wait forever

Quick Checklist

  • Explore site with browse open <url>

  • Test interactions manually

  • Create project: pnpm dlx @browserbasehq/sdk-functions init <name>

  • Fix package.json immediately (Step 3)

  • Run pnpm install

  • Write automation in index.ts

  • Test locally: pnpm bb dev index.ts

  • Verify with curl

  • Deploy: pnpm bb publish index.ts

  • Test production via API

  • Save function ID

Code Fix Needed (For Maintainers)

File: /src/commands/functions.ts

Lines: 146-158 Function: initFunction()

Replace the current packageJson object with:

const packageJson = { name, version: '1.0.0', description: ${name} function, main: 'index.js', type: 'module', packageManager: 'pnpm@10.14.0', scripts: { dev: 'pnpm bb dev index.ts', publish: 'pnpm bb publish index.ts', }, dependencies: { '@browserbasehq/sdk-functions': '^0.0.5', 'playwright-core': '^1.58.0', }, devDependencies: { '@types/node': '^25.0.10', 'typescript': '^5.9.3', }, };

This will eliminate the "No functions were built" error for all new projects.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

browser

No summary provided by upstream source.

Repository SourceNeeds Review
General

functions

No summary provided by upstream source.

Repository SourceNeeds Review
General

fetch

No summary provided by upstream source.

Repository SourceNeeds Review