# Puppeteer

Source: https://docs.evomi.com/proxy-instructions/integration-guides/puppeteer/

This guide explains how to use Evomi proxies with Puppeteer, a Node.js library for controlling headless Chrome/Chromium. Puppeteer supports proxy authentication through the `page.authenticate()` method.

## Prerequisites

- Node.js 18+ installed
- Your Evomi proxy credentials (username and password)

## Installation

```bash
npm install puppeteer
```

Puppeteer automatically downloads a compatible Chromium binary during installation.

## Configuration

Puppeteer sets the proxy server via a Chrome launch argument and handles authentication separately with `page.authenticate()`.

```javascript
const puppeteer = require('puppeteer');

(async () => {
  const proxyHost = 'rp.evomi.com';
  const proxyPort = 1000;
  const proxyUser = 'your_username';
  const proxyPass = 'your_password_session-anychars_mode-speed';

  const browser = await puppeteer.launch({
    args: [`--proxy-server=http://${proxyHost}:${proxyPort}`],
  });

  const page = await browser.newPage();

  await page.authenticate({
    username: proxyUser,
    password: proxyPass,
  });

  await page.goto('https://ip.evomi.com/s');
  const body = await page.evaluate(() => document.body.innerText);
  console.log('Proxy IP:', body.trim());

  await browser.close();
})();
```

Replace `your_username` with your Evomi username and `your_password` with your actual password (keep the `_session-anychars_mode-speed` parameters).

## Explanation

1. **`--proxy-server` argument**: Tells Chromium to route all traffic through the specified proxy. Credentials are not included in this URL.
2. **`page.authenticate()`**: Sets the proxy username and password. This must be called **before** any navigation on the page.
3. **Verification**: Navigating to `https://ip.evomi.com/s` returns the IP seen by the server, which should be the proxy IP.

## Using SOCKS5 with proxy-chain

Puppeteer's `page.authenticate()` only works with HTTP/HTTPS proxies. For SOCKS5 proxies, use the [proxy-chain](https://www.npmjs.com/package/proxy-chain) package to create a local forwarder:

```bash
npm install proxy-chain
```

```javascript
const puppeteer = require('puppeteer');
const proxyChain = require('proxy-chain');

(async () => {
  const proxyUser = 'your_username';
  const proxyPass = 'your_password_session-anychars_mode-speed';

  const oldProxyUrl = `socks5://${proxyUser}:${proxyPass}@rp.evomi.com:1002`;
  const newProxyUrl = await proxyChain.anonymizeProxy(oldProxyUrl);

  const browser = await puppeteer.launch({
    args: [`--proxy-server=${newProxyUrl}`],
  });

  const page = await browser.newPage();
  await page.goto('https://ip.evomi.com/s');
  const body = await page.evaluate(() => document.body.innerText);
  console.log('Proxy IP:', body.trim());

  await browser.close();
  await proxyChain.closeAnonymizedProxy(newProxyUrl);
})();
```

`proxy-chain` creates a local proxy forwarder that handles the SOCKS5 authentication on your behalf, so Puppeteer can connect without needing `page.authenticate()`.

## Evomi Proxy Endpoints

| Proxy Type | HTTP | HTTPS | SOCKS5 |
|---|---|---|---|
| **Residential** | `rp.evomi.com:1000` | `rp.evomi-proxy.com:1001` | `rp.evomi.com:1002` |
| **Mobile** | `mp.evomi.com:3000` | `mp.evomi-proxy.com:3001` | `mp.evomi.com:3002` |
| **Datacenter** | `dcp.evomi.com:2000` | `dcp.evomi-proxy.com:2001` | `dcp.evomi.com:2002` |

HTTPS endpoints use the `evomi-proxy.com` domain — that is the hostname our TLS certificate covers, and it reaches the same servers. A client that verifies certificates will reject the `evomi.com` form on the HTTPS port.

## Running the Script

```bash
node puppeteer_proxy_test.js
```

The proxy IP will be printed to the console.

## Tips and Troubleshooting

- **Credentials**: Double-check your proxy host, port, username, and password. The password format is `your_password_session-anychars_mode-speed`.
- **Authenticate before navigation**: `page.authenticate()` must be called before `page.goto()`. If called after, it will not apply to the current page.
- **New pages need re-authentication**: Each new `page` created via `browser.newPage()` requires its own `page.authenticate()` call.
- **Headless mode**: Puppeteer runs headless by default. Add `headless: false` to `launch()` to see the browser window for debugging.
- **SSL errors**: If you encounter certificate errors with specific target sites, you can add `'--ignore-certificate-errors'` to the `args` array. Use with caution in production.
- **Timeouts**: For slow connections, increase the navigation timeout: `page.goto(url, { timeout: 60000 })`.
