Embed a live browser in your app
Live URLs are regular HTTPS pages, so you can embed the live browser inside your own UI with an iframe. This guide covers the required iframe permissions, sizing, view-only mode, and connection behavior.
- A Browserless API token from your account dashboard
- A Puppeteer or Playwright session connected to Browserless, with a page-level CDP session
- Familiarity with the Hybrid Automation guide
- Permission to add an iframe and update the Content Security Policy (CSP) for your app
Overview
Create a Live URL from your automation, then use the returned liveURL as the iframe source. The URL contains a short-lived viewer ID instead of your Browserless API token.
Step 1: Create and configure the Live URL
Set Live URL options when you mint the URL:
const { liveURL } = await cdp.send('Browserless.liveURL', {
interactable: false,
resizable: false,
showBrowserInterface: true,
timeout: 120000,
});
View-only embedding
Use interactable: false when viewers should only watch. Browserless drops viewer input on the server before it reaches the remote browser.
Iframe sizing
With the default resizable: true, the remote viewport follows the iframe size. With resizable: false, the viewer letterboxes the stream to preserve the viewport and aspect ratio set by your automation.
Give the iframe a stable height through CSS. A percentage height only works when its parent also has an explicit height.
Step 2: Add the iframe
Render the Live URL in your app:
<iframe
src={liveURL}
sandbox="allow-same-origin allow-scripts"
allow="clipboard-read; clipboard-write"
style={{ width: '100%', height: '100%', border: 0 }}
title="Browserless live browser"
/>
The viewer is a script-driven canvas application, so it needs allow-same-origin and allow-scripts. The allow attribute enables copy and paste between the viewer and the remote page.
On success, the iframe loads the remote browser canvas and starts a same-origin WebSocket from the Live URL page to the Browserless host.
Keyboard focus
The iframe must have focus before it can forward keyboard input. This is especially important in Safari. Focus it from a user-initiated event:
openViewerButton.addEventListener('click', () => {
liveViewIframe.focus();
});
Step 3: Allow the Browserless origin
If your app sends a CSP header, add the Browserless region you connect to under frame-src:
Content-Security-Policy: frame-src 'self' https://production-sfo.browserless.io;
Use your actual Browserless host, such as production-lon.browserless.io, production-ams.browserless.io, or your self-hosted Enterprise origin. The stream WebSocket runs inside the framed page on that same origin, so your parent page doesn't need a separate connect-src entry for it. Corporate firewalls and proxies must still allow WSS traffic to that host.
Viewer behavior and limits
- Each Live URL accepts up to five concurrent viewers. A sixth connection receives HTTP
429; closing a viewer frees its slot. showBrowserInterface: trueadds tabs with live titles and favicons, tab switching and closing, back and forward controls, the current URL, and a draggable page scrollbar.- Copy and paste work in both directions. The viewer supports Ctrl-based shortcuts in Windows and Linux, and Command-based shortcuts on macOS.
- When the stream drops unexpectedly, the viewer shows Reconnecting… and retries three times, before asking the viewer to reload.
- Minting a Live URL keeps the browser available for the requested Live URL timeout, but never past the browser session's absolute duration limit.
- After Browserless fills a stored credential, it closes active viewers and refuses new Live URL connections. See the 1Password security model.
FAQ & Troubleshooting
Why is the iframe blank or blocked?
Allow the Browserless host in your page's frame-src CSP directive and make sure HTTPS and WSS traffic to /live/* can pass through your firewall or proxy. See Network Endpoints & VPN/Proxy Tips.
Why doesn't typing work inside the iframe?
Mint the URL with interactable: true, then focus the iframe from a click or another user-initiated event. Input remains blocked when the URL was created with interactable: false, regardless of client-side CSS or JavaScript.
Why doesn't copy or paste work?
Add allow="clipboard-read; clipboard-write" to the iframe. The browser can still require the viewer to grant clipboard permission or interact with the frame before clipboard access succeeds.