Skip to main content
Version: v2

Recording Sessions with LiveURL

The recording and LiveURL integration provides a comprehensive solution for capturing browser sessions while enabling human intervention when needed. This approach is essential for workflows that require both automated navigation and manual user input, such as authentication flows, CAPTCHA handling, and complex form interactions.

Key Features

Session Recording: Capture complete browser sessions as WebM video files with audio support

LiveURL Generation: Create shareable URLs for real-time user interaction without exposing API tokens

Event-Driven Monitoring: Track session completion and user actions through CDP events

Hybrid Automation: Seamlessly transition between programmatic and manual control

tip

All recordings are saved in WebM format, which provides efficient compression while maintaining quality. This format is compatible with most modern browsers and video players.

Prerequisites and Setup

Before implementing recording with LiveURL, ensure you have the necessary environment configured:

# Install required packages  
npm install puppeteer-core

# Set environment variables
export BROWSERLESS_TOKEN="your-api-key-here"

Connection Requirements

Recording functionality requires specific connection parameters:

  • The record=true parameter must be included in the WebSocket connection string
  • CDP session creation is required for accessing Browserless-specific commands
  • Appropriate timeout values should be configured for your use case

Basic Recording with LiveURL

Here's the fundamental implementation pattern that combines recording with interactive sessions:

import puppeteer from 'puppeteer-core';  
import fs from 'fs';

// Set your Browserless.io API token here
// Get your token from: https://www.browserless.io/
const BROWSERLESS_TOKEN = 'YOUR_API_TOKEN_HERE'; // Replace with your actual token

const queryParams = new URLSearchParams({
token: BROWSERLESS_TOKEN,
timeout: 180000,
headless: true,
}).toString();

(async () => {
let browser = null;

try {
// Connect with recording enabled
browser = await puppeteer.connect({
browserWSEndpoint: `wss://production-sfo.browserless.io?record=true&${queryParams}`,
});

const page = await browser.newPage();
await page.goto('https://example.com/login', {
waitUntil: 'networkidle2'
});

// Initialize CDP session for Browserless features
const cdp = await page.createCDPSession();

// Start recording (this command does not return any data)
await cdp.send("Browserless.startRecording");

// Generate LiveURL for user interaction (30 seconds timeout)
const { liveURL } = await cdp.send('Browserless.liveURL', {
timeout: 30000 // 30 seconds
});
console.log('Share this URL:', liveURL);

// Wait for 30 seconds instead of user interaction
await new Promise(resolve => setTimeout(resolve, 30000));

// Stop recording and save
const response = await cdp.send("Browserless.stopRecording");
const recordingBuffer = Buffer.from(response.value, "binary");
await fs.promises.writeFile("./session-recording.webm", recordingBuffer);

} catch (error) {
console.error('Recording failed:', error);
} finally {
if (browser) await browser.close();
}
})();

Advanced Session Monitoring

For more sophisticated workflows, you can implement custom monitoring logic that provides visual feedback to users:

// Enhanced monitoring with visual feedback  
await page.waitForFunction(() => {
const currentUrl = window.location.href;
const isSuccess = currentUrl.includes('logged-in') ||
currentUrl.includes('dashboard') ||
document.querySelector('.post-login') !== null;

if (isSuccess) {
// Create success notification
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed; top: 20px; left: 50%;
transform: translateX(-50%); background-color: #4CAF50;
color: white; padding: 15px 30px; border-radius: 5px;
z-index: 9999; font-family: Arial, sans-serif;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
`;
notification.textContent = 'Login successful - you can close this tab';
document.body.appendChild(notification);
return true;
}
return false;
}, { timeout: 60000 });

Custom Recording Triggers

Start recording only after specific conditions are met:

await page.waitForSelector('.login-form');
await cdp.send("Browserless.startRecording");

Audio Recording

Audio is automatically captured with the recording - no additional configuration needed.

Conditional Recording

Only record if a specific element is present:

const hasLoginForm = await page.$('.login-form');
if (hasLoginForm) {
await cdp.send("Browserless.startRecording");
}

Next Steps

Ready to explore more features? Continue your journey with these essential topics: