Browser Recordings
rrweb session replay for any browser an agent drives via Playwright. Capture the DOM, mouse, network, and console — then scrub the replay in your dashboard.
Overview
Recordings are browser sessions, not agent tool-call traces. Whenever your agent uses Playwright (for E2E tests, scraping, or debugging a frontend), wrap the page with CloudClawer's recording helper and you'll get a frame-accurate replay backed by rrweb.
The recording captures the DOM mutations, mouse moves, input events, scroll positions, and network responses that rrweb supports. Replay it in the Recordings dashboardexactly as if you were watching the agent's browser live.
Capturing a recording
Install the hooks package (bundled with the cloudclawer CLI) and import the recording helper into your Playwright script:
import { chromium } from 'playwright';
import { startRecording } from 'cloudclawer-hooks/record.mjs';
const browser = await chromium.launch();
const page = await browser.newPage();
const rec = await startRecording(page, { title: 'Login flow E2E' });
await page.goto('http://localhost:3000');
await page.getByRole('button', { name: 'Sign in' }).click();
// … exercise the feature …
const { filePath, eventCount, recordingId } = await rec.stop();
console.log(`Recorded ${eventCount} events → ${filePath}`);
await browser.close();startRecording injects the rrweb client into the page from cdn.jsdelivr.net (pin version rrweb@2.0.0-alpha.4 to match the replay player), re-injects after navigation, and buffers events in the page context until you call stop(). The local file lands at ~/.cloudclawer-recordings/<id>.json.
inlineImages: true and inlineFonts: true so recordings of localhoststill play back on other devices that can't reach your machine. Pass recordCanvas: trueif you're recording a WebGL canvas — it requires preserveDrawingBuffer: true on the WebGL context.Uploading
After rec.stop() writes the JSON to disk, upload it with the bundled CLI:
cloudclawer-hooks record-upload ~/.cloudclawer-recordings/1747000000-3a8f9c.jsonThe CLI requests a presigned S3 URL from CloudClawer, streams the file directly to S3, and returns both the recording ID and the dashboard play URL. The recording is then listed on cloudclawer.com/recordings immediately.
Watching the replay
Open Recordings for a list of every upload, then click any item to launch the rrweb player. The player gives you:
- Timeline scrubber — drag to any moment in the session.
- Speed control — 0.5×, 1×, 2×, or 4× playback.
- Skip inactive periods — auto-fast-forwards quiet stretches.
- Full DOM inspection — open devtools on the replay iframe; the recorded DOM is real.
Storage & limits
Recordings are stored in S3 under your account namespace at users/{username}/recordings/{recordingId}.json. Hard limits:
- 500 recordings per account. Oldest are evicted as you upload new ones.
- 90-day TTL. Recordings older than 90 days are deleted by S3 lifecycle policy.
- List, fetch, and delete endpoints accept your CloudClawer API key as
X-API-Key.
GET /u/dkr/recordings # list
GET /u/dkr/recordings/{id} # fetch metadata + presigned download URL
DELETE /u/dkr/recordings/{id} # delete now (also removes the S3 object)Privacy & what's captured
rrweb captures only the page context it was injected into — it does not see your clipboard, other browser tabs, or anything outside the Playwright-controlled page. Specifically:
- Captured: DOM snapshots, attribute and text mutations, input values, mouse moves, scroll, viewport size, network metadata (URLs + timing) when enabled.
- Not captured by default: canvas pixel data (opt in with
recordCanvas), cross-origin iframe contents, response bodies.
data-rr-block attribute, or call rrweb with maskInputOptions in your own integration.