Skip to main content

Launch Options

Launch options configure how each browser session starts and behaves. You pass them as query parameters or as a JSON object on the WebSocket connection URL when connecting via Puppeteer, Playwright, or any CDP client.

These are per-session settings. For server-level configuration (concurrency limits, timeouts, health checks), see the Docker Configuration Reference.

Configuration Methods

There are two ways to pass launch options:

  • Query parameters go directly in the connection URL (e.g., &headless=false&stealth=true). Best for simple, standalone settings.
  • The launch object is a JSON string passed as a single launch query parameter. Use it for browser-level options that contain arrays or nested values, like args: [...], where brackets and quotes require encoding.

Both methods can be combined. Query parameters take precedence when the same option appears in both.

import puppeteer from "puppeteer-core";

const browser = await puppeteer.connect({
browserWSEndpoint: `ws://localhost:3000/chromium?token=YOUR_API_TOKEN_HERE&stealth=true&blockAds=true&timeout=60000`,
});

Quick Examples

These examples connect to an enterprise instance with a launch object that sets a custom window size via Chrome flags.

import puppeteer from "puppeteer-core";

const launch = btoa(JSON.stringify({
args: ["--window-size=1920,1080"],
}));

const browser = await puppeteer.connect({
browserWSEndpoint: `ws://localhost:3000/chromium?token=YOUR_API_TOKEN_HERE&launch=${launch}`,
});

const page = await browser.newPage();
await page.goto("https://example.com");
await browser.close();

Launch Object Options

The launch parameter accepts a JSON object with these properties:

OptionTypeDefaultDescription
argsstring[][]Chrome command-line flags passed to the browser process
headlessbooleantrueRun the browser in headless mode
stealthbooleanfalseEnable stealth mode to reduce automation detection
slowMonumber0Add a delay (in ms) between each operation
ignoreDefaultArgsboolean | string[]falseRemove all or specific default Chrome flags
acceptInsecureCertsbooleanfalseAccept self-signed and expired TLS certificates
warning

acceptInsecureCerts replaces the older ignoreHTTPSErrors parameter, which has been renamed and deprecated by the Puppeteer team. Both are accepted for backwards compatibility, but use acceptInsecureCerts in new code.

Encoding the Launch Value

The launch value must be encoded before appending it to the URL. Base64 is the simplest approach because it avoids escaping brackets, quotes, and commas.

Base64 encoding

import puppeteer from "puppeteer-core";

const launch = btoa(JSON.stringify({
args: ["--window-size=1280,720"],
headless: true,
}));

const browser = await puppeteer.connect({
browserWSEndpoint: `ws://localhost:3000/chromium?token=YOUR_API_TOKEN_HERE&launch=${launch}`,
});

URL encoding

import puppeteer from "puppeteer-core";

const launch = JSON.stringify({
args: ["--window-size=1280,720"],
});

const browser = await puppeteer.connect({
browserWSEndpoint: `ws://localhost:3000/chromium?token=YOUR_API_TOKEN_HERE&launch=${encodeURIComponent(launch)}`,
});

Chrome Flags

Chrome flags are passed via the args array inside the launch object. Enterprise deployments support the full set of Chrome command-line switches, with no flag allowlist.

Before encoding:

{"args": ["--window-size=1920,1080", "--lang=en-US", "--disable-web-security"]}

Common flags:

  • --window-size=WIDTH,HEIGHT sets the initial browser window dimensions
  • --lang=LOCALE sets the browser UI language
  • --proxy-server=HOST:PORT routes traffic through a proxy
  • --proxy-bypass-list=HOSTS skips the proxy for specific hosts
  • --disable-web-security disables same-origin policy (useful for testing)
  • --user-data-dir=PATH sets a persistent browser profile directory
  • --disable-gpu disables GPU hardware acceleration
  • --disable-dev-shm-usage writes shared memory files to /tmp instead of /dev/shm
  • --disable-features=FEATURE1,FEATURE2 disables specific Chromium features
  • --enable-features=FEATURE1,FEATURE2 enables specific Chromium features
Automatic WebRTC protection

The enterprise image adds WebRTC leak prevention flags to every session automatically. These prevent your server's real IP from leaking through WebRTC:

  • --webrtc-ip-handling-policy=disable_non_proxied_udp
  • --force-webrtc-ip-handling-policy
  • --disable-features=WebRtcHideLocalIpsWithMdns
  • --enforce-webrtc-ip-permission-check

You do not need to add these yourself.

Query Parameter Options

These parameters go directly in the connection URL as query strings.

ParameterTypeDefaultDescription
tokenstringAPI authentication token (matches the TOKEN env var)
timeoutnumber30000Session timeout in milliseconds. The server-level TIMEOUT env var sets the upper bound.
headlessbooleantrueRun the browser in headless mode
stealthbooleanfalseEnable stealth mode to reduce automation detection
blockAdsbooleanfalseBlock ads using the built-in uBlock Origin extension
blockConsentModalsbooleanfalseBlock cookie consent modals and banners
humanlikebooleanfalseEnable humanlike browsing behavior (mouse movements, typing delays)
recordbooleanfalseRecord the session for later playback (requires license support)
replaybooleanfalseEnable session replay (requires license support)
solveCaptchasbooleanfalseAutomatically solve captchas during the session (requires license support)

Example with multiple query parameters:

import puppeteer from "puppeteer-core";

const browser = await puppeteer.connect({
browserWSEndpoint: `ws://localhost:3000/chromium?token=YOUR_API_TOKEN_HERE&stealth=true&blockAds=true&timeout=120000`,
});

Browser Context Settings

Some browser settings operate at the page or context level and cannot be configured through launch parameters or Chrome flags. These include viewport dimensions, locale, timezone, user agent, and geolocation.

Set these using CDP commands or library-level APIs after connecting, before your first navigation.

import puppeteer from "puppeteer-core";

const browser = await puppeteer.connect({
browserWSEndpoint: `ws://localhost:3000/chromium?token=YOUR_API_TOKEN_HERE`,
});

const page = await browser.newPage();

// Configure context-level settings before navigating
await page.setViewport({ width: 1920, height: 1080 });
await page.setUserAgent(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
);

const cdp = await page.createCDPSession();
await cdp.send("Emulation.setTimezoneOverride", {
timezoneId: "America/New_York",
});
await cdp.send("Emulation.setLocaleOverride", {
locale: "en-US",
});
await cdp.send("Emulation.setGeolocationOverride", {
latitude: 40.7128,
longitude: -74.006,
accuracy: 100,
});

// Now navigate
await page.goto("https://example.com");
await browser.close();

Issue these commands before your first page.goto() call. Any navigation that happens before the overrides are in place will use the browser's default settings.

Stealth mode and context settings

When stealth mode is active, the enterprise image auto-configures timezone and browser locale based on proxy location data. You only need to set these manually for non-stealth sessions or when you want to override the automatic values.

Automatic CDP Behaviors

The enterprise image intercepts and modifies certain CDP commands behind the scenes:

  • Viewport normalization: If a client sends an Emulation.setDeviceMetricsOverride with the default 800x600 dimensions, the image resets width and height to 0 (full viewport). This prevents detection via a hardcoded viewport size.
  • Target filtering: Target.setDiscoverTargets responses filter out worker threads, reducing automation fingerprints visible to page scripts.
  • Browser close protection: Browser.close and Browser.crash commands return a success response without terminating the browser process. This prevents client code from accidentally killing a shared session.
  • Download path enforcement: Browser.setDownloadBehavior calls are redirected to the configured downloads directory.

These behaviors are transparent. You do not need to account for them in your code.

Enterprise vs. BaaS Differences

What enterprise adds

  • All Chrome flags: Pass any Chrome command-line switch via args. BaaS restricts flags to an allowlist.
  • --user-data-dir: Point to a persistent browser profile directory for cookies, cache, and local storage across sessions.
  • Full ignoreDefaultArgs: Remove any default Chrome flags without restriction.
  • Custom extensions and fonts: Mount extensions and font files directly into the container via Docker volumes.

What stays the same

  • Launch JSON format: Same JSON structure and encoding methods (base64, URL encoding).
  • Core query parameters: token, timeout, stealth, blockAds, headless, and other standalone params work identically.
  • Library connection methods: Puppeteer connect(), Playwright connectOverCDP(), and Playwright connect() all work the same way.

What BaaS has that enterprise does not

  • Managed residential proxies: The proxy, proxyCountry, proxyCity, proxyState, proxySticky, proxyLocaleMatch, and proxyPreset parameters are BaaS-only. For enterprise, configure proxies via the --proxy-server Chrome flag or an external proxy service.

Next Steps