Playwright integration

Connect Playwright to Crawlhub proxies.

Add an authenticated HTTP proxy to your browser automation, then check one page before running a larger job.

Start free
Go to setup guide
Crawlhub.ai and Playwright integration guide. Authenticated proxies for browser automation.
Playwright integration guide. View full size

What does Playwright handle?

Playwright controls Chromium, Firefox and WebKit. Your proxy chooses the network route; your browser context owns cookies, local storage and other session state.

Browser or context scope

Set a proxy when launching the browser, or when creating an individual browser context.

Proxy-only credentials

The local bridge handles upstream login, keeping proxy credentials out of the browser’s website authentication handler.

Browser rendering

Use the browser when your data depends on JavaScript or page interaction.

Explicit session state

Reuse a context for a related sequence. Changing contexts does not automatically request a new proxy IP.

Setup guide

Set up Playwright with Crawlhub

Start with one connection check. Add your workload after the route works.

Playwright
Credentials stay at the proxy bridge
const bridge = await createProxyBridge();
const browser = await chromium.launch({
  proxy: { server: bridge.url },
});

Before you start

An active Crawlhub proxy and its assigned host, port, username and password. PROXY_SERVER includes the protocol and port, but no username or password. Use the values from your account; these examples do not activate a proxy.

Node.js 22.12 or newer, the browser library and proxy-chain. This Chromium recipe uses a loopback-only bridge for authenticated HTTP(S) upstream proxies, so proxy credentials are not handed to website authentication challenges.

  1. Install the browser library

    Create a project folder and install Playwright. Its browser download is separate from installing the JavaScript package.

    Run in your terminal
    npm init -y
    npm install playwright proxy-chain
    npx playwright install chromium
  2. Add your connection details

    Set the variables in the shell that will run the script. A proxy server URL such as http://HOST:PORT can carry HTTPS destination traffic using CONNECT. Pick the proxy protocol assigned to your service.

    The example starts a loopback-only proxy bridge automatically. The bridge connects to the assigned upstream proxy; the browser receives only the local URL.

    Run in your terminal
    export PROXY_SERVER='http://YOUR_PROXY_HOST:YOUR_PORT'
    export PROXY_USERNAME='YOUR_PROXY_USERNAME'
    export PROXY_PASSWORD='YOUR_PROXY_PASSWORD'
    export TARGET_URL='https://example.com/'
  3. Run a page request

    Download both files below into the same project folder, then run playwright.mjs. The shared helper handles upstream authentication; the browser loads through its local endpoint.

    The example checks the response status, prints the title and closes both the browser and bridge on completion or failure.

    Run in your terminal
    node playwright.mjs
    Download proxy_bridge.mjs
    proxy_bridge.mjs
    import { Server } from 'proxy-chain';
    
    export async function createProxyBridge() {
      const { PROXY_SERVER, PROXY_USERNAME, PROXY_PASSWORD } = process.env;
      if (!PROXY_SERVER || !PROXY_USERNAME || !PROXY_PASSWORD) {
        throw new Error('Set PROXY_SERVER, PROXY_USERNAME and PROXY_PASSWORD.');
      }
      const upstream = new URL(PROXY_SERVER);
      if (!['http:', 'https:'].includes(upstream.protocol) ||
          upstream.username || upstream.password || upstream.search ||
          upstream.hash || (upstream.pathname && upstream.pathname !== '/')) {
        throw new Error('Use an HTTP(S) proxy server URL without credentials, a path or a query.');
      }
      upstream.username = PROXY_USERNAME;
      upstream.password = PROXY_PASSWORD;
      const server = new Server({
        host: '127.0.0.1',
        port: 0,
        prepareRequestFunction: () => ({ upstreamProxyUrl: upstream.href }),
      });
      await server.listen();
      return {
        url: `http://127.0.0.1:${server.port}`,
        close: () => server.close(true),
      };
    }
    Download playwright.mjs
    playwright.mjs
    import { chromium } from 'playwright';
    import { createProxyBridge } from './proxy_bridge.mjs';
    
    const bridge = await createProxyBridge();
    let browser;
    try {
      browser = await chromium.launch({
        headless: true,
        proxy: { server: bridge.url },
      });
      const context = await browser.newContext();
      const page = await context.newPage();
      const response = await page.goto(process.env.TARGET_URL || 'https://example.com/', {
        waitUntil: 'domcontentloaded', timeout: 30000,
      });
      if (!response || !response.ok()) {
        throw new Error(`Page returned HTTP ${response?.status() ?? 'unknown'}.`);
      }
      console.log(JSON.stringify({ status: response.status(), title: await page.title() }));
      await context.close();
    } finally {
      try { await browser?.close(); } finally { await bridge.close(); }
    }
  4. Verify the route and grow the job

    A successful request confirms that the page loaded, but it does not by itself prove the exit IP. Run the same code against an IP-check endpoint you trust, inspect the returned address, then switch to your target. Keep the requested location and session settings consistent when comparing results.

    For a multi-step session, keep the same browser context and use the sticky-session username assigned by your service. Set concurrency and navigation timeouts deliberately rather than launching an unlimited number of browsers.

When the connection fails

Use the error to narrow down the next check.

407 authentication error

Check the upstream login and username parameters in the bridge environment. Website httpCredentials are a separate mechanism and should not contain proxy credentials.

Navigation timeout

Test the proxy with one public page first. Distinguish connection failure from a page that keeps network activity open.

Different data between runs

Record the exit location and session parameters. Browser context state and proxy IP state are separate.

Connect Playwright to Crawlhub

Connect Playwright. Start with one request. Residential, ISP and datacenter proxies. Start free or talk to an expert.
Start free
Playwright connection setup. View full size
Start free

Contact us

Tell us what you want to collect.

See our Privacy Notice for how we handle your message.

Your message is sent to hello@crawlhub.ai. Please do not include passwords or API keys.