How to Connect Puppeteer or Playwright to Browserless
Updated
To connect an existing Puppeteer or Playwright script to Browserless, replace your local launch() call with a connect() call that points at the Browserless WebSocket endpoint and includes your API key as a token. Your automation code — page navigation, selectors, scraping logic — stays the same. Browserless documents this as a one-line change, and provides a free plan of 1k sessions per month with no credit card required, so you can test the swap before committing.
What you need first
- A Browserless API key. The site's "Get your API key" flow issues one; the free plan covers 1k runs/sessions a month without a card.
- A working Puppeteer or Playwright script that currently launches a local browser.
- The
puppeteer-corepackage (or your Playwright equivalent) rather than the full bundled-download package, since you no longer need a local Chromium binary.
The core change: launch() → connect()
The mechanism is straightforward: instead of starting a browser process on your machine, your script opens a WebSocket connection to a browser already running in Browserless's cloud. The connection URL carries your credentials:
wss://chrome.browserless.io?token=YOUR_API_KEY
Everything after the connection — newPage(), goto(), your selectors and extraction — is unchanged. That is why the migration is described as a one-line swap rather than a rewrite.
Puppeteer example
The site's own snippet uses puppeteer-core:
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://chrome.browserless.io?token=YOUR_API_KEY',
});
const page = await browser.newPage();
await page.goto('https://example.com');
// Your automation code here...
await browser.close();
Note the two differences from a local script: connect() instead of launch(), and browserWSEndpoint instead of launch options like headless or executablePath.
Playwright example
Playwright follows the same pattern — connect over the WebSocket endpoint rather than launching:
import { chromium } from 'playwright';
const browser = await chromium.connectOverCDP(
'wss://chrome.browserless.io?token=YOUR_API_KEY'
);
const page = await browser.newPage();
await page.goto('https://example.com');
// Your automation code here...
await browser.close();
The site lists Playwright alongside Puppeteer and REST as supported connection methods, and its code tabs show playwright.ts next to puppeteer.ts and rest.sh. If your Playwright version or setup expects a different connection call than connectOverCDP, check the Browserless docs linked from the site — the endpoint and token format are the parts that stay constant.
REST example
If you don't want a persistent browser session, Browserless also exposes a REST interface (the rest.sh tab on the site). This suits one-shot scrape or screenshot tasks where you send a request and get content back, rather than driving a browser interactively.
Verify the connection works
- Run your modified script once against a simple target such as
https://example.com. - Confirm you get a
200 OK-style successful response and the expected page content — the site's own demo shows abrowserless target.com 200 OKresult. - Check that
browser.close()(or your disconnect call) completes cleanly, since you're closing a remote session rather than a local process. - If you hit an authentication error, re-check that the token is appended as
?token=YOUR_API_KEYand hasn't been truncated or wrapped in quotes incorrectly.
Common snags and what they mean
- Local launch options no longer apply. Arguments like
executablePath,headless, or bundled-Chromium flags belong tolaunch(). When you switch toconnect(), remove them; Browserless manages the browser environment. - Version mismatches. The site's production log example shows a
Chrome 130 → 131: launcher args rejectederror as a typical local-browser failure. Connecting to a managed endpoint removes that class of problem, but keep your client library reasonably current so the protocol matches. - Login walls and bot detection. If your script stalls on a CAPTCHA or a login page, that's a browser-layer issue, not a code issue. Browserless offers stealth, CAPTCHA handling, residential proxies, and Authenticated Profiles — log in once and reuse the session across runs instead of embedding credentials in code.
- Session limits. The free plan's 1k sessions/month is a real ceiling; heavy test loops can exhaust it. Check the pricing page for current plan details before scaling.
When this approach fits
Swapping to Browserless makes sense if your scripts work locally but fail in production due to crashes, memory limits, lost sessions, or blocks — the failure modes the site's log excerpt illustrates. It's less necessary if you only run occasional local scrapes where a bundled browser is fine. The connection change itself is small either way, so the practical test is: run one script against the endpoint, confirm it returns data, and decide from there.