ScreenshotNeo

BlogHow-to

How to Take Website Screenshots with Chromium Using a Proxy

Configure a proxy for Chromium with Playwright or Puppeteer, choose the right page-ready condition, and capture full pages or elements.

By the ScreenshotNeo team4 October 20269 min read

To take a website screenshot with Chromium through a proxy, configure the proxy when launching Chromium or when creating an isolated browser context, navigate to the page, wait for the content you need, and call the browser automation framework’s screenshot API. Playwright supports HTTP(S) and SOCKSv5 proxy settings with optional credentials and bypass hosts; Puppeteer exposes page and element screenshot methods. The examples below use Playwright for proxy configuration and include a Puppeteer alternative.

1. Choose the proxy scope

Use a browser-level proxy when every page in that browser should use the same route. Use a context-level proxy when separate isolated sessions need different proxy settings. A context is also a useful boundary for cookies and other session state. Playwright documents both scopes and its proxy configuration options. See the Playwright proxy documentation.

Approach Use it when Tradeoff
Playwright browser-level proxy All contexts in the browser should use one proxy. Simple shared configuration; less suitable for sessions that need different routes.
Playwright context-level proxy Different isolated contexts need different proxy settings. Configure the proxy for each context.
Chromium command-line flag You launch Chromium directly or need a Chromium-level setting. You manage the browser process and its lifecycle yourself.

Use a proxy URL and credentials supplied by your proxy provider. Playwright documents a proxy server plus optional username, password, and bypass hosts. Authentication and behavior can vary by proxy deployment, so follow the provider’s current instructions and verify connectivity with the target site.

2. Install Playwright and Chromium

For a Node.js project, install Playwright and its Chromium browser build:

npm install playwright
npx playwright install chromium

Browser installation and page traffic are separate proxy concerns. If you need to download the browser behind a firewall, Playwright documents using HTTPS_PROXY for installation. If that proxy intercepts TLS with a private certificate authority, its documentation describes setting NODE_EXTRA_CA_CERTS before installation. Those settings do not replace configuring a proxy on the browser or context for page requests. See Playwright’s browser installation guidance.

3. Capture a page with Playwright

Save this as screenshot.mjs. Set the proxy URL and optional credentials in environment variables rather than putting secrets in source control. This example creates a context with its own proxy, waits for a page-specific selector, captures a full-page PNG, and closes the browser even if navigation or capture fails.

import { chromium } from 'playwright';

const proxyServer = process.env.PROXY_SERVER;
if (!proxyServer) {
  throw new Error('Set PROXY_SERVER, for example http://proxy.example:8080');
}

const proxy = { server: proxyServer };
if (process.env.PROXY_USERNAME) proxy.username = process.env.PROXY_USERNAME;
if (process.env.PROXY_PASSWORD) proxy.password = process.env.PROXY_PASSWORD;
if (process.env.PROXY_BYPASS) proxy.bypass = process.env.PROXY_BYPASS;

const browser = await chromium.launch({ headless: true });
try {
  const context = await browser.newContext({ proxy });
  try {
    const page = await context.newPage();
    await page.goto('https://example.com', {
      waitUntil: 'domcontentloaded',
      timeout: 60_000,
    });
    await page.locator('h1').waitFor({ state: 'visible', timeout: 15_000 });
    await page.screenshot({ path: 'page.png', fullPage: true });
  } finally {
    await context.close();
  }
} finally {
  await browser.close();
}

Run it with the proxy details supplied by your provider:

PROXY_SERVER='http://proxy.example:8080' \
PROXY_USERNAME='your-username' \
PROXY_PASSWORD='your-password' \
node screenshot.mjs

For a SOCKSv5 proxy, use the SOCKSv5 server URL format your provider specifies. Playwright’s documented proxy server options support HTTP(S) and SOCKSv5. Avoid printing proxy credentials in logs. If credentials contain shell-special characters, set them through your deployment’s secret or environment-variable mechanism rather than editing the command unsafely.

Browser-level proxy instead

If all contexts should share the same proxy, pass the proxy to chromium.launch() and create the context without a proxy option:

const browser = await chromium.launch({
  headless: true,
  proxy: {
    server: process.env.PROXY_SERVER,
    username: process.env.PROXY_USERNAME,
    password: process.env.PROXY_PASSWORD,
    bypass: process.env.PROXY_BYPASS,
  },
});
const context = await browser.newContext();

Omit optional fields you do not use. A bypass list is useful for hosts that should connect directly; use the syntax supported by the Playwright version in your project.

4. Choose a reliable readiness condition

The screenshot is only as useful as the state captured. domcontentloaded is a quick starting point, but it does not mean that client-rendered content, images, or fonts are ready. Puppeteer’s screenshot guide shows a navigation using networkidle2; treat network-idle waits as one possible signal, not a universal rule. Analytics, polling, long-lived connections, or other background requests can prevent a page from becoming idle.

  • Wait for a selector when a particular heading, chart, or result marks readiness.
  • Wait for an application signal when the page exposes a stable state such as a completed-render attribute.
  • Wait for images or fonts when visual completeness depends on them. A page-specific readiness check is more reliable than an arbitrary delay.
  • Use a timeout so a stalled page does not hold a capture job indefinitely, and report which readiness condition timed out.

For example, replace the heading wait with the selector that represents the content you need. Do not assume a successful navigation response means the desired application content rendered.

5. Capture a specific element

Playwright can capture a locator directly. This is useful for a chart, card, or report section without the rest of the page:

const chart = page.locator('#revenue-chart');
await chart.waitFor({ state: 'visible', timeout: 15_000 });
await chart.screenshot({ path: 'chart.png' });

For a full-page image, use fullPage: true on page.screenshot(). For a viewport-only capture, omit it. Screenshot output options such as path, image type, and quality are documented by the framework; check the API for the installed version.

6. Puppeteer alternative

Puppeteer’s documented screenshot API captures a page, and ElementHandle.screenshot() captures an element. Configure Chromium’s proxy at launch with its proxy-server argument, then navigate and take the capture:

import puppeteer from 'puppeteer';

const proxyServer = process.env.PROXY_SERVER;
if (!proxyServer) throw new Error('Set PROXY_SERVER');

const browser = await puppeteer.launch({
  headless: true,
  args: [`--proxy-server=${proxyServer}`],
});
try {
  const page = await browser.newPage();
  await page.goto('https://example.com', {
    waitUntil: 'domcontentloaded',
    timeout: 60_000,
  });
  await page.waitForSelector('h1', { visible: true, timeout: 15_000 });
  await page.screenshot({ path: 'page.png', fullPage: true });

  const chart = await page.$('#revenue-chart');
  if (chart) await chart.screenshot({ path: 'chart.png' });
} finally {
  await browser.close();
}

Install Puppeteer and its compatible browser according to the Puppeteer installation guide. Proxy authentication depends on the proxy service and deployment. The dossier does not establish a universal credential recipe for every proxy scheme; check the provider’s instructions instead of assuming that a launch argument handles all authentication challenges.

7. Configure Chromium directly

When managing Chromium yourself, its documented --proxy-server flag accepts a single proxy URI, per-scheme mappings, or direct://. For example:

chromium --headless --proxy-server="http://proxy.example:8080" \
  --screenshot=page.png https://example.com

Chromium also documents --no-proxy-server to disable proxy use. A single URI applies to all URLs; per-scheme mappings can route schemes through different proxies. Consult the Chromium network settings documentation for accepted flag syntax. Framework-based automation is usually more convenient when you need explicit readiness waits, repeatable sessions, and element screenshots.

8. Headless mode and repeatability

Record the automation framework version, Chromium version, headless mode, viewport, and host environment when screenshot output needs to be comparable. Playwright notes that rendering can vary with operating system, browser version, settings, hardware, power source, and headless mode. Keep these variables stable for visual baselines. Puppeteer documents headless: true for its new headless mode and headless: 'shell' for the old headless shell. Playwright documents a separate headless-shell build and an opt-in to newer headless mode via the Chromium channel. Check the framework’s current documentation before selecting a mode: Playwright Chromium modes and Puppeteer headless modes.

9. Reliability, performance, and cost

  • Reuse browser processes carefully. Launching a browser has setup cost; a long-running worker can reuse a browser while creating fresh contexts for isolated jobs. Close contexts and browsers when finished, and recycle workers according to your operational limits.
  • Set explicit timeouts. Bound navigation and readiness waits. Classify proxy connection errors, navigation failures, selector timeouts, and screenshot failures separately so retries target the right problem.
  • Retry selectively. A transient network failure may justify a bounded retry. A missing selector or blocked destination usually needs diagnosis rather than repeated immediate attempts.
  • Keep proxy capacity in mind. Proxy routing adds a network dependency and can affect reachability and page load time. No universal latency or success rate applies; measure against your own provider, destinations, and capture workload.
  • Limit capture size. Full-page screenshots can be large and may require more memory and processing than viewport or element captures. Capture only the region you need, and choose the output format and dimensions appropriate to the downstream use.
  • Budget for the whole job. Consider browser compute, proxy usage, retries, storage, and transfer costs. This research provides no benchmark or provider pricing, so estimate using your own workload and vendor terms.

10. Troubleshooting

Symptom Likely cause What to check or change
Chromium cannot connect to the proxy Wrong scheme, host, port, DNS, or unreachable proxy. Confirm the exact server URL and port with the provider; check network reachability from the machine running Chromium.
Proxy authentication fails Credentials are missing, malformed, or unsupported in the current deployment. Verify provider-specific authentication requirements and that credentials are passed to the intended Playwright proxy scope. Do not assume every scheme uses the same challenge behavior.
Browser downloads fail behind a firewall Browser installation traffic is not configured through the download proxy, or TLS interception uses an untrusted CA. Follow Playwright’s browser installation proxy guidance; configure the documented certificate handling if applicable. This is separate from page traffic proxy configuration.
Page loads directly instead of through the proxy The proxy was configured for downloads or environment variables only, not Chromium page traffic. Set Playwright’s launch/context proxy or Chromium’s --proxy-server flag, then verify the route using your proxy provider’s diagnostics.
Navigation succeeds but screenshot is blank or incomplete The page has not rendered the target content, or a client-side load is still in progress. Wait for a page-specific selector or application signal; check image/font readiness if those matter.
Network-idle wait never completes Polling, analytics, streaming, or persistent requests keep the network active. Use a selector or application readiness condition instead of relying on global idleness.
TLS certificate errors The destination certificate is invalid for the browser environment, or a proxy intercepts TLS using a CA Chromium does not trust. Check the destination and provider certificate setup. For browser installation, follow the framework’s documented custom-CA instructions. Avoid disabling certificate checks as a routine fix.
Visual baselines differ between runs Browser version, host OS, headless mode, viewport, fonts, or hardware differ. Pin and record the rendering environment and use consistent capture settings.
Full-page capture is slow or memory-heavy The document is very long or contains large assets. Capture a viewport or element, reduce unnecessary page content, or split the capture by sections.

11. Or skip the browser setup

For a one-request capture without managing Chromium or a proxy, ScreenshotNeo is a website screenshot API and MCP server for developers. The API accepts a URL and returns an image or PDF; see the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card required.

FAQ

Does setting HTTPS_PROXY route Chromium page traffic?

Do not treat browser-download environment variables as equivalent to a browser proxy setting. Configure page traffic through Playwright’s proxy option or Chromium’s proxy flag.

Should I use HTTP or SOCKSv5?

Use the protocol your proxy provider supplies and that your automation framework supports. Playwright documents HTTP(S) and SOCKSv5 proxy settings.

Is a successful HTTP response enough to know the screenshot is ready?

No. A client-rendered page may still be updating. Wait for the specific content or application state the capture requires.

Why do two headless runs look different?

Browser version, headless mode, operating system, hardware, settings, and page timing can affect rendering. Keep the environment and capture conditions consistent when comparing images.

References