Playwright Proxy Setup
Playwright offers the most flexible proxy architecture of any browser automation framework. It supports proxy configuration at both the browser level and the browser context level, with built-in authentication support across all three engines (Chromium, Firefox, and WebKit). This context-level proxy support is unique to Playwright and enables true per-tab proxy isolation without workarounds.
When you set a proxy on browser.newContext(), Playwright creates an isolated browsing session with its own cookies, storage, and proxy connection. This means you can run 10 tabs with 10 different Hex Proxies credentials in a single browser process, each appearing as a completely separate user from a different location.
Prerequisites
Before you begin, make sure you have: - An active Hex Proxies account with proxy credentials - Node.js 18+ - npm or yarn - Playwright (downloads Chromium, Firefox, and WebKit)
Installation
npm install playwrightBasic Proxy Configuration
Playwright accepts a proxy object directly in launch() or newContext(). Unlike Puppeteer, authentication is part of the proxy config object rather than a separate API call.
const browser = await chromium.launch({ proxy: { server: 'http://gate.hexproxies.com:8080', username: 'user', password: 'pass', }, });
const context = await browser.newContext({ viewport: { width: 1920, height: 1080 }, userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' + 'AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36', });
const page = await context.newPage();
try { await page.goto('https://httpbin.org/ip', { timeout: 30000, waitUntil: 'networkidle', }); const content = await page.textContent('body'); console.log(content); } finally { await browser.close(); } ```
Per-Context Proxy Isolation
Set different proxies per browser context for parallel multi-geo scraping. Each context maintains separate cookies, storage, and proxy connections:
const context2 = await browser.newContext({
proxy: {
server: 'http://gate.hexproxies.com:8081',
username: 'user2',
password: 'pass2',
},
});Cross-Browser Proxy Testing
Playwright supports Chromium, Firefox, and WebKit with the same proxy API. Test your proxy integration across engines to verify that Hex Proxies IPs work consistently regardless of browser fingerprint. Some anti-bot systems respond differently to Firefox vs Chrome TLS fingerprints.
Configuration Options
- **Proxy Server** -- gate.hexproxies.com:8080 in the proxy.server field of launch() or newContext().
- **Authentication** -- username and password fields in the proxy config object.
- **Per-Context Proxy** -- Pass different proxy configs to each newContext() call for multi-IP sessions.
- **Bypass List** -- proxy.bypass field to exclude domains from proxying (e.g., "localhost,*.internal.com").
- **Browser Engine** -- chromium, firefox, or webkit with identical proxy API.
Error Handling
Playwright provides detailed error messages for proxy failures with actionable context.
- page.goto: net::ERR_PROXY_CONNECTION_FAILED
- - The browser engine cannot connect to the proxy gateway
- - Test proxy reachability: curl -x http://gate.hexproxies.com:8080 https://httpbin.org/ip
- - Ensure no local proxy or VPN conflicts with Playwright's proxy config
2. page.goto: Timeout 30000ms exceeded - Proxied page load took too long - Increase timeout or use waitUntil: 'domcontentloaded' - Check if the destination is blocking the proxy IP
3. browserContext.newPage: Target page, context or browser has been closed - The context was disposed while creating a page - Ensure context creation completes before opening pages - Check for unhandled promise rejections in async flows
4. net::ERR_PROXY_AUTH_FAILED (Chromium) - The proxy rejected the supplied credentials - Verify username and password match your Hex Proxies dashboard - Check for special characters that need escaping
5. Protocol error (Network.enable): Browser closed - Browser process crashed, often from memory pressure - Limit concurrent contexts to 5-10 per browser instance - Use browser.close() and relaunch periodically for long runs ```
Use page.on('crash') to detect page crashes and context.on('close') for context lifecycle events.