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
- 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 playwrightandnpx playwright install chromium. - Python:
pip install playwrightandplaywright 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
| Product | Line in your dashboard | Notes |
|---|---|---|
| Static ISP proxies | IP:PORT:USER:PASS | One line per dedicated IP. With IP whitelisting turned on, the line is just IP:PORT and no password is sent. |
| Rotating residential and mobile | HOST:PORT:USER:PASS | Generated 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
Split your line
Server ishttp://HOST:PORT; username and password go in their own fields. - 2
Set the proxy
At launch for one proxy for everything, or per context for one proxy per account or location. - 3
Add a bypass list if needed
Usebypass: "localhost,127.0.0.1"for local services that shouldn't go through the proxy. - 4
Check the exit IP
Openhttps://api.ipify.organd read the body text.
Playwright proxy in Node.js
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();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
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()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
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.
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.
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
| Problem | Likely cause | Fix |
|---|---|---|
| Browser does not support socks5 proxy authentication | SOCKS5 server combined with username and password. | Use http://HOST:PORT with the same credentials, or SOCKS5 with IP whitelisting. |
| 407 or ERR_TUNNEL_CONNECTION_FAILED | Credentials embedded in server (dropped) or mistyped. | Move them into the username and password fields. |
| Timeout on page.goto | Wrong 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 unreachable | Localhost 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.