In plain English: Puppeteer is a Node.js library that controls Chrome from a script. It can run headless, with no window on screen, or headful, in a normal window you can watch, and people use it to take screenshots, test their own sites and read pages that rely on JavaScript. A proxy goes in with two small steps: tell Chrome the proxy's address when it starts, then hand each tab your username and password. Both steps are below, ready to paste.
Quick start in 3 steps
- Install Puppeteer and check your proxy details with cURL.
- Start Chrome with the
--proxy-serverargument. - Call
page.authenticate()with your login before you open a page, then look at the IP it prints.
Have these to hand
- Node.js 18 or newer. Node.js is what runs JavaScript outside a browser.
- Puppeteer, installed with npm, Node's package manager.
- Your proxy details. The examples use four stand-ins,
HOST,PORT,USERandPASS, for the values in your dashboard.
Install Puppeteer:
npm install puppeteerThen, before writing any script, make sure the details work, so you're never fixing two problems at once:
curl --proxy http://USER:PASS@HOST:PORT https://api.ipify.orgIf the reply is the proxy's IP address, carry on.
Step 1: start Chrome with the proxy
The proxy goes in as a launch argument. Only the host and port belong here, because Chrome won't accept a username and password in this flag:
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({
headless: "new",
args: ["--proxy-server=http://HOST:PORT"]
});
const page = await browser.newPage();
await page.goto("https://api.ipify.org");
console.log(await page.content());
await browser.close();
})();Using IP whitelisting, where your own IP address is approved in the dashboard? Then you're already finished. Most people sign in with a username and password, though, so read on.
Step 2: give each page your login
Puppeteer's page.authenticate() answers the proxy's login request for you. Call it before the first page loads:
const puppeteer = require("puppeteer");
const HOST = "HOST", PORT = "PORT", USER = "USER", PASS = "PASS";
(async () => {
const browser = await puppeteer.launch({
headless: "new",
args: [`--proxy-server=http://${HOST}:${PORT}`]
});
const page = await browser.newPage();
await page.authenticate({ username: USER, password: PASS });
await page.goto("https://api.ipify.org", { waitUntil: "networkidle2" });
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();
})();Remember that authenticate works tab by tab. Open another page and you'll need to call it again for that one.
Keeping sessions apart
A browser context works like a separate private window: it has its own cookies and cache, so two contexts never share a login. That helps when you run a few sessions side by side through different sticky endpoints, meaning addresses that keep the same IP for a while:
const context = await browser.createBrowserContext();
const page = await context.newPage();
await page.authenticate({ username: USER, password: PASS });
await page.goto("https://example.com");
// ... do work ...
await context.close();Older tutorials call this createIncognitoBrowserContext; recent Puppeteer versions renamed it createBrowserContext, so use whichever your version has. And if your plan gives you a single rotating gateway, you can skip contexts for this purpose: every new connection through the gateway already gets a new IP, with the same login.
Save data by skipping images
Our plans are priced per gigabyte, and a full browser downloads every picture, video and font on a page. If all you need is the text, block the heavy files:
await page.setRequestInterception(true);
page.on("request", (req) => {
const blocked = ["image", "media", "font"];
if (blocked.includes(req.resourceType())) req.abort();
else req.continue();
});For jobs that only read HTML or JSON, this can cut your data use a great deal without breaking how the page works.
Check the connection
Don't take it on trust. This prints the IP address the website sees:
await page.goto("https://api.ipify.org?format=json");
const body = await page.evaluate(() => document.body.innerText);
console.log("Proxy IP:", JSON.parse(body).ip);Compare it with your own address. You can also put the same details into our proxy checker, and run a DNS leak test if privacy matters for your project.
Which type should I pick?
- Your own test site, or straightforward public pages: datacenter proxies, the lower-cost choice.
- Sites that are strict about where visitors come from: residential proxies or residential premium, both with home-connection addresses.
- Content aimed at people on a particular phone network: mobile proxies.
The proxies page explains each type in more detail.
Common mistakes
- Putting the login in
--proxy-server. Chrome ignores it. Usepage.authenticate()instead. - Authenticating too late. Call it first, then go to the page. The other way round, the first request fails.
- A new tab with no login. Each extra tab needs its own authenticate call.
- Not closing the browser. The examples finish with browser.close() or context.close(); leave that out and Chrome keeps running after your script ends.
Is this allowed?
Puppeteer can fire off a lot of requests very quickly, so slow it down on purpose. Check the target site's robots.txt, follow its terms of service, keep your request rate modest, and collect only public data you're permitted to use. Don't use it to get round logins, defeat anti-fraud checks or gather personal data without a lawful basis. Careful scripts keep your proxies in good shape and your project running.
Beginner questions
Does Puppeteer come with its own Chrome?
Yes. Installing Puppeteer also downloads a copy of Chrome that it knows how to drive, so there's nothing else to install.
Can I see what the browser is doing?
Yes. In the launch options, set headless to false and Chrome opens in an ordinary window.
Will blocking images break pages?
Text and links still load. A page that needs its pictures to make sense, such as a photo gallery, won't look right, so block only what you don't need.