Claude
Skills
Sign in
Back

cloudflare-browser-rendering

Included with Lifetime
$97 forever

Complete knowledge domain for Cloudflare Browser Rendering - Headless Chrome automation with Puppeteer and Playwright on Cloudflare Workers for screenshots, PDFs, web scraping, and browser automation workflows. Use when: taking screenshots, generating PDFs from HTML or URLs, web scraping content, crawling websites, browser automation tasks, testing web applications, managing browser sessions, performing batch browser operations, integrating with AI for content extraction, or encountering browser rendering errors, XPath selector errors, browser timeout issues, concurrency limits, memory exceeded errors, or "Cannot read properties of undefined (reading 'fetch')" errors. Keywords: browser rendering cloudflare, @cloudflare/puppeteer, @cloudflare/playwright, puppeteer workers, playwright workers, screenshot cloudflare, pdf generation workers, web scraping cloudflare, headless chrome workers, browser automation, puppeteer.launch, playwright.chromium.launch, browser binding, session management, puppeteer.sessions, puppeteer.connect, browser.close, browser.disconnect, XPath not supported, browser timeout, concurrency limit, keep_alive, page.screenshot, page.pdf, page.goto, page.evaluate, incognito context, session reuse, batch scraping, crawling websites

Web Dev

What this skill does


# Cloudflare Browser Rendering - Complete Reference

Production-ready knowledge domain for building browser automation workflows with Cloudflare Browser Rendering.

**Status**: Production Ready ✅
**Last Updated**: 2025-10-22
**Dependencies**: cloudflare-worker-base (for Worker setup)
**Latest Versions**: @cloudflare/[email protected], @cloudflare/[email protected], [email protected]

---

## Table of Contents

1. [Quick Start (5 minutes)](#quick-start-5-minutes)
2. [Browser Rendering Overview](#browser-rendering-overview)
3. [Puppeteer API Reference](#puppeteer-api-reference)
4. [Playwright API Reference](#playwright-api-reference)
5. [Session Management](#session-management)
6. [Common Patterns](#common-patterns)
7. [Pricing & Limits](#pricing--limits)
8. [Known Issues Prevention](#known-issues-prevention)
9. [Production Checklist](#production-checklist)

---

## Quick Start (5 minutes)

### 1. Add Browser Binding

**wrangler.jsonc:**
```jsonc
{
  "name": "browser-worker",
  "main": "src/index.ts",
  "compatibility_date": "2023-03-14",
  "compatibility_flags": ["nodejs_compat"],
  "browser": {
    "binding": "MYBROWSER"
  }
}
```

**Why nodejs_compat?** Browser Rendering requires Node.js APIs and polyfills.

### 2. Install Puppeteer

```bash
npm install @cloudflare/puppeteer
```

### 3. Take Your First Screenshot

```typescript
import puppeteer from "@cloudflare/puppeteer";

interface Env {
  MYBROWSER: Fetcher;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const { searchParams } = new URL(request.url);
    const url = searchParams.get("url") || "https://example.com";

    // Launch browser
    const browser = await puppeteer.launch(env.MYBROWSER);
    const page = await browser.newPage();

    // Navigate and capture
    await page.goto(url);
    const screenshot = await page.screenshot();

    // Clean up
    await browser.close();

    return new Response(screenshot, {
      headers: { "content-type": "image/png" }
    });
  }
};
```

### 4. Deploy

```bash
npx wrangler deploy
```

Test at: `https://your-worker.workers.dev/?url=https://example.com`

**CRITICAL:**
- Always pass `env.MYBROWSER` to `puppeteer.launch()` (not undefined)
- Always call `browser.close()` when done (or use `browser.disconnect()` for session reuse)
- Use `nodejs_compat` compatibility flag

---

## Browser Rendering Overview

### What is Browser Rendering?

Cloudflare Browser Rendering provides headless Chromium browsers running on Cloudflare's global network. Use familiar tools like Puppeteer and Playwright to automate browser tasks:

- **Screenshots** - Capture visual snapshots of web pages
- **PDF Generation** - Convert HTML/URLs to PDFs
- **Web Scraping** - Extract content from dynamic websites
- **Testing** - Automate frontend tests
- **Crawling** - Navigate multi-page workflows

### Two Integration Methods

| Method | Best For | Complexity |
|--------|----------|-----------|
| **Workers Bindings** | Complex automation, custom workflows, session management | Advanced |
| **REST API** | Simple screenshot/PDF tasks | Simple |

**This skill covers Workers Bindings** (the advanced method with full Puppeteer/Playwright APIs).

### Puppeteer vs Playwright

| Feature | Puppeteer | Playwright |
|---------|-----------|------------|
| **API Familiarity** | Most popular | Growing adoption |
| **Package** | `@cloudflare/[email protected]` | `@cloudflare/[email protected]` |
| **Session Management** | ✅ Advanced APIs | ⚠️ Basic |
| **Browser Support** | Chromium only | Chromium only (Firefox/Safari not yet supported) |
| **Best For** | Screenshots, PDFs, scraping | Testing, frontend automation |

**Recommendation**: Use Puppeteer for most use cases. Playwright is ideal if you're already using it for testing.

---

## Puppeteer API Reference

### puppeteer.launch()

Launch a new browser instance.

**Signature:**
```typescript
await puppeteer.launch(binding: Fetcher, options?: LaunchOptions): Promise<Browser>
```

**Parameters:**
- `binding` (required) - Browser binding from `env.MYBROWSER`
- `options` (optional):
  - `keep_alive` (number) - Keep browser alive for N milliseconds (max: 600000 = 10 minutes)

**Returns:** `Promise<Browser>` - Browser instance

**Example:**
```typescript
const browser = await puppeteer.launch(env.MYBROWSER, {
  keep_alive: 60000 // Keep alive for 60 seconds
});
```

**CRITICAL:** Must pass `env.MYBROWSER` binding. Error "Cannot read properties of undefined (reading 'fetch')" means the binding wasn't passed.

---

### puppeteer.connect()

Connect to an existing browser session.

**Signature:**
```typescript
await puppeteer.connect(binding: Fetcher, sessionId: string): Promise<Browser>
```

**Use Cases:**
- Reuse existing browser sessions for performance
- Share browser instance across multiple Workers
- Reduce startup time

**Example:**
```typescript
const sessionId = "478f4d7d-e943-40f6-a414-837d3736a1dc";
const browser = await puppeteer.connect(env.MYBROWSER, sessionId);
```

---

### puppeteer.sessions()

List currently running browser sessions.

**Signature:**
```typescript
await puppeteer.sessions(binding: Fetcher): Promise<SessionInfo[]>
```

**Returns:**
```typescript
interface SessionInfo {
  sessionId: string;
  startTime: number;
  connectionId?: string;  // Present if worker is connected
  connectionStartTime?: number;
}
```

**Example:**
```typescript
const sessions = await puppeteer.sessions(env.MYBROWSER);
// Find sessions without active connections
const freeSessions = sessions.filter(s => !s.connectionId);
```

---

### puppeteer.history()

List recent sessions (both open and closed).

**Signature:**
```typescript
await puppeteer.history(binding: Fetcher): Promise<HistoryEntry[]>
```

**Returns:**
```typescript
interface HistoryEntry {
  sessionId: string;
  startTime: number;
  endTime?: number;
  closeReason?: number;
  closeReasonText?: string; // "NormalClosure", "BrowserIdle", etc.
}
```

**Use Case:** Monitor usage patterns and debug session issues.

---

### puppeteer.limits()

Check current account limits and available sessions.

**Signature:**
```typescript
await puppeteer.limits(binding: Fetcher): Promise<LimitsInfo>
```

**Returns:**
```typescript
interface LimitsInfo {
  activeSessions: Array<{ id: string }>;
  maxConcurrentSessions: number;
  allowedBrowserAcquisitions: number;
  timeUntilNextAllowedBrowserAcquisition: number; // milliseconds
}
```

**Example:**
```typescript
const limits = await puppeteer.limits(env.MYBROWSER);
if (limits.allowedBrowserAcquisitions === 0) {
  return new Response("Rate limit reached", { status: 429 });
}
```

---

### Browser API

Methods available on the `Browser` object returned by `launch()` or `connect()`.

#### browser.newPage()

Create a new page (tab) in the browser.

**Signature:**
```typescript
await browser.newPage(): Promise<Page>
```

**Example:**
```typescript
const page = await browser.newPage();
await page.goto("https://example.com");
```

**Performance Tip:** Reuse browser instances and open multiple tabs instead of launching new browsers.

---

#### browser.sessionId()

Get the current browser session ID.

**Returns:** `string` - Session ID

**Example:**
```typescript
const sessionId = browser.sessionId();
console.log("Current session:", sessionId);
```

---

#### browser.close()

Close the browser and terminate the session.

**Signature:**
```typescript
await browser.close(): Promise<void>
```

**When to use:** When you're completely done with the browser and want to free resources.

---

#### browser.disconnect()

Disconnect from the browser WITHOUT closing it.

**Signature:**
```typescript
await browser.disconnect(): Promise<void>
```

**When to use:** Session reuse - allows another Worker to connect to the same session later.

**Example:**
```typescript
// Keep session alive for reuse
const sessionId = browser.sessionId();
await browser.disconnect(); // Don't close, just disconnect
// Later: puppeteer.connect(env.MYBROWSER, sessionId)
``

Related in Web Dev