Configuring proxies in Puppeteer and Playwright
Step-by-step instructions for hooking proxies into Puppeteer and Playwright with JavaScript code, error handling, and IP rotation within a session.
Puppeteer: basic integration
The simplest option — pass the proxy through args at browser launch:
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({
args: [
'--proxy-server=http://gate.proxyprovider.com:7777',
'--no-sandbox'
]
});
const page = await browser.newPage();
await page.goto('https://api.ipify.org');
console.log(await page.content()); // your new IPPuppeteer: with authentication
Most providers require user:password auth. Puppeteer doesn't support it directly through args, so you need page.authenticate():
const page = await browser.newPage();
await page.authenticate({
username: 'your-username',
password: 'your-password'
});
await page.goto('https://target.com');For residential providers the user:pass format usually contains session parameters:
// Decodo: sticky 30 min, US gateway
username: 'user-spXXXX-country-us-session-abc123'
password: 'your-password'
// SOAX: sticky 1 hour, package id
username: 'package-XXX-country-us-sessionid-abc'
password: 'your-password'Playwright: setup
Playwright's API is a bit cleaner — the proxy is passed into the browser context:
const { chromium } = require('playwright');
const browser = await chromium.launch();
const context = await browser.newContext({
proxy: {
server: 'http://gate.proxyprovider.com:7777',
username: 'your-username',
password: 'your-password'
}
});
const page = await context.newPage();
await page.goto('https://api.ipify.org');Rotating IPs in code
For rotation within one script, create a new context for each "work batch":
async function scrapeUrls(urls) {
for (const url of urls) {
const context = await browser.newContext({
proxy: { server: getNextProxy() } // your rotation function
});
const page = await context.newPage();
await page.goto(url);
// ... process
await context.close(); // releases the IP
}
}Bandwidth optimisation
The biggest saving is blocking media and scripts you don't need:
await page.setRequestInterception(true);
page.on('request', req => {
const resourceType = req.resourceType();
if (['image', 'stylesheet', 'font', 'media'].includes(resourceType)) {
req.abort();
} else {
req.continue();
}
});On sites like Amazon this saves 60-80% of bandwidth, turning a 10 GB/day workload into 2-3 GB/day. With per-gigabyte providers, that's a 3-4× cost reduction.
Caveat: blocking JS entirely will break React/SPA pages. For those, only block image, font, and media — keep stylesheet and script enabled.