Skip to content
Browser automation (Node.js & Python)

How to use proxies with Playwright (Node.js and Python)

In Playwright, pass proxy: { server: "http://HOST:PORT", username: "USERNAME", password: "PASSWORD" } to chromium.launch() or to browser.newContext(). Python uses the same keys. Keep the credentials in the username and password fields, never in the server URL.

What you need

Playwright has first-class proxy support, including a different proxy per browser context, and it handles the proxy's authentication challenge for you. It works the same in Chromium, Firefox and WebKit.
  • An active CleanProxies plan: static ISP proxies for fixed US IPs, or rotating residential / mobile proxies for pools. The trial works too.
  • Your credential line from the dashboard's proxy manager: host (or IP), port, username and password.
  • Node.js: npm install playwright and npx playwright install chromium.
  • Python: pip install playwright and playwright install chromium.

New to proxies? For the overview, read Proxies with Python Requests, Playwright and Puppeteer. This guide goes deeper on Playwright only.

Your CleanProxies credentials

Every CleanProxies product works over HTTP(S) and SOCKS5. This is what the dashboard gives you.
ProductLine in your dashboardNotes
Static ISP proxiesIP:PORT:USER:PASSOne line per dedicated IP. With IP whitelisting turned on, the line is just IP:PORT and no password is sent.
Rotating residential and mobileHOST:PORT:USER:PASSGenerated in the proxy manager. The username carries the location and session you pick, so generate a new list to change them.

Most tools want the same details as a URL: http://USERNAME:PASSWORD@HOST:PORT for HTTP(S) or socks5://USERNAME:PASSWORD@HOST:PORT for SOCKS5. The examples on this page use those placeholders; copy the host, port, username and password from your CleanProxies dashboard. To convert a whole list at once, paste it into the proxy list formatter.

How to set up CleanProxies in Playwright

  1. 1

    Split your line

    Server is http://HOST:PORT; username and password go in their own fields.
  2. 2

    Set the proxy

    At launch for one proxy for everything, or per context for one proxy per account or location.
  3. 3

    Add a bypass list if needed

    Use bypass: "localhost,127.0.0.1" for local services that shouldn't go through the proxy.
  4. 4

    Check the exit IP

    Open https://api.ipify.org and read the body text.

Playwright proxy in Node.js

Launch-level proxyJavaScript
import { chromium } from "playwright";

const browser = await chromium.launch({
  proxy: { server: "http://HOST:PORT", 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();
Proxy per contextJavaScript
const browser = await chromium.launch();

const context = await browser.newContext({
  proxy: { server: "http://IP1:PORT", username: "USER1", password: "PASS1" },
});
const page = await context.newPage();
await page.goto("https://api.ipify.org");

Playwright proxy in Python

Sync APIPython
from playwright.sync_api import sync_playwright

PROXY = {"server": "http://HOST:PORT", "username": "USERNAME", "password": "PASSWORD"}

with sync_playwright() as p:
    browser = p.chromium.launch(proxy=PROXY)
    page = browser.new_page()
    page.goto("https://api.ipify.org")
    print("Exit IP:", page.text_content("body"))
    browser.close()
Async API, one context per ISP proxyPython
import asyncio
from playwright.async_api import async_playwright

PROXIES = [
    {"server": "http://IP1:PORT", "username": "USER1", "password": "PASS1"},
    {"server": "http://IP2:PORT", "username": "USER2", "password": "PASS2"},
]

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        for proxy in PROXIES:
            context = await browser.new_context(proxy=proxy)
            page = await context.new_page()
            await page.goto("https://api.ipify.org")
            print(await page.text_content("body"))
            await context.close()
        await browser.close()

asyncio.run(main())

SOCKS5 in Playwright

Playwright rejects SOCKS5 with a username and password in every browser, with the error "Browser does not support socks5 proxy authentication". Use the HTTP form of your CleanProxies credentials, or server: "socks5://IP:PORT" with no credentials on an ISP proxy authorized by IP whitelisting.

Playwright also rebuilds the server value from protocol, host and port, so credentials written as http://user:pass@host:port there are silently dropped.

Static ISP vs rotating residential in Playwright

Both products use the same setup. What changes is how long an IP stays with you.

Static ISP proxies

A context per dedicated US ISP IP is the cleanest pattern for logged-in automation: each context has its own cookies and its own address, and the address never changes.

Static ISP ProxiesAs low as $0.75/IP

Rotating residential proxies

Use sticky lines from the CleanProxies generator for anything with more than one page load per identity, so the IP holds for the whole flow. Rotating lines fit one-shot fetches across many pages or countries.

Rotating Residential ProxiesAs low as $0.63/GB

Verify your exit IP

Both examples print the exit IP. In tests, assert on it: fetch https://api.ipify.org at the start of a run and fail fast if it equals your machine's IP.

Open What is my IP? through the proxy to see the address and headers a website receives, or paste up to ten lines into the free proxy checker to test connectivity, latency and exit IP before you start.

Troubleshooting Playwright proxy errors

ProblemLikely causeFix
Browser does not support socks5 proxy authenticationSOCKS5 server combined with username and password.Use http://HOST:PORT with the same credentials, or SOCKS5 with IP whitelisting.
407 or ERR_TUNNEL_CONNECTION_FAILEDCredentials embedded in server (dropped) or mistyped.Move them into the username and password fields.
Timeout on page.gotoWrong host or port, or a slow target with a short timeout.Test the line with curl -x; raise timeout in goto for heavy pages.
Local dev server unreachableLocalhost traffic sent to the proxy.Add bypass: "localhost,127.0.0.1".

Still stuck? Our 24/7 support team answers fast: contact us with the error and the line you used (leave the password out).

Playwright proxy FAQs

Yes. Pass proxy to newContext (new_context in Python). Each context then has its own proxy, cookies and storage inside one browser.

Get CleanProxies for Playwright

Super clean US ISP IPs from $0.75/IP with unlimited bandwidth, rotating residential from $0.63/GB and mobile from $0.79/GB. Instant delivery, 99.9% uptime and 24/7 support.