NewUnlimited residential proxies: unmetered traffic on a fixed price. From $33.25/day

JavaScript ยท Integration guide

How to use proxies with Playwright

Playwright accepts proxy settings, username and password included, at launch or for each browser context. This guide covers authentication, sticky IPs per context, location matching and resilient navigation.

  • 6 steps
  • 12 min setup
  • Copy-paste code

Before you start

  • Node.js 20 or newer, or Python 3.10 or newer for the Python example
  • Playwright with at least one browser installed
  • A Proxonym residential or mobile plan
Get proxy credentials

Already a customer? Your username and password are in the dashboard.

  1. Install Playwright and a browser

    Install the library, then download the browser you plan to drive. Save the JavaScript examples as .mjs files to use import and top-level await.

    Shell
    npm install playwright
    npx playwright install chromium
  2. Launch a browser through the gateway

    Pass the gateway, username and password in the proxy option. Playwright answers the gateway login for you, so no extra authentication step is needed.

    JavaScript
    // launch.mjs
    import { chromium } from 'playwright';
    
    const browser = await chromium.launch({
      proxy: {
        server: 'http://gw.proxonym.com:8000',
        username: 'USERNAME',
        password: 'PASSWORD',
      },
    });
    const page = await browser.newPage();
    await page.goto('https://api.ipify.org');
    console.log('Exit IP:', await page.textContent('body'));
    await browser.close();
  3. Give each context its own sticky IP

    A page opens many connections, so use a -session- ID to keep them on one IP. Contexts accept their own proxy, which lets one browser run several identities, each with its own country and session.

    JavaScript
    // contexts.mjs
    import { randomBytes } from 'node:crypto';
    import { chromium } from 'playwright';
    
    const browser = await chromium.launch();
    
    for (const country of ['us', 'gb', 'de']) {
      const context = await browser.newContext({
        proxy: {
          server: 'http://gw.proxonym.com:8000',
          username: `USERNAME-country-${country}-session-${randomBytes(4).toString('hex')}-lifetime-30`,
          password: 'PASSWORD',
        },
      });
      const page = await context.newPage();
      await page.goto('https://api.ipify.org');
      console.log(country, await page.textContent('body'));
      await context.close();
    }
    await browser.close();
  4. Match locale and timezone to the IP

    Target a country, state or city in the username and set the context locale and timezone to match, so the browser does not contradict its exit IP.

    JavaScript
    const context = await browser.newContext({
      proxy: {
        server: 'http://gw.proxonym.com:8000',
        username: 'USERNAME-country-fr-city-paris-session-p4r1s-lifetime-30',
        password: 'PASSWORD',
      },
      locale: 'fr-FR',
      timezoneId: 'Europe/Paris',
    });
    const page = await context.newPage();
    await page.goto('https://ipinfo.io/json');
    console.log(await page.textContent('body'));
  5. Save traffic and retry failed navigations

    Block images, media and fonts to cut metered traffic, and retry navigations that fail with a tunnel error or a timeout. A gateway refusal surfaces as an error such as net::ERR_TUNNEL_CONNECTION_FAILED.

    JavaScript
    await context.route('**/*', (route) => {
      const type = route.request().resourceType();
      return ['image', 'media', 'font'].includes(type) ? route.abort() : route.continue();
    });
    
    async function gotoWithRetry(page, url, tries = 3) {
      for (let attempt = 1; ; attempt++) {
        try {
          return await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60_000 });
        } catch (err) {
          console.error(`attempt ${attempt}:`, err.message.split('\n')[0]);
          if (attempt === tries) throw err;
        }
      }
    }
    
    const response = await gotoWithRetry(page, 'https://example.com');
    console.log('Status:', response?.status());
  6. Use the same settings in Python

    Playwright for Python takes the same proxy keys. Install it with pip install playwright and playwright install chromium, then pass the proxy at launch or in new_context().

    Python
    from playwright.sync_api import sync_playwright
    
    with sync_playwright() as p:
        browser = p.chromium.launch(proxy={
            "server": "http://gw.proxonym.com:8000",
            "username": "USERNAME-country-us",
            "password": "PASSWORD",
        })
        page = browser.new_page()
        page.goto("https://api.ipify.org")
        print("Exit IP:", page.text_content("body"))
        browser.close()

Frequently asked questions

Can Playwright use SOCKS5 with a username and password?

Playwright can connect to SOCKS5 servers, but its username and password fields apply to HTTP proxies. Use http://gw.proxonym.com:8000 whenever you authenticate with credentials. The HTTP endpoint tunnels HTTPS through CONNECT and accepts the same targeting and session parameters, so you lose nothing by choosing it for browser automation.

Should I set the proxy at launch or per context?

Set it at launch when every page should share one identity. Set it per context when you need several IPs or locations in parallel, because contexts are much lighter than separate browsers and keep cookies and connections apart. Contexts without a proxy of their own use the launch-level setting, if there is one.

Does Playwright for Python work the same way?

Yes. The proxy option takes the same server, username and password keys in launch() and new_context(), and the same username parameters control rotation, sticky sessions and geo-targeting. The async API behaves identically, so you can port the JavaScript examples on this page line by line.

Why does page.goto time out through the proxy?

Heavy pages and slow targets are the usual causes. The gateway ends a target request after 60 seconds with a 504, so wait for domcontentloaded rather than networkidle, block images and media, and retry with a fresh session ID. Repeated tunnel errors instead point to credentials, balance or a blocked target.

Ready to plug it in? Get your credentials.

Pick a plan, copy your username and password from the dashboard and run the code above.

  • Pay as you go
  • Instant activation
  • Crypto accepted
  • 24/7 support