chrome-ua

View script Copied!

Print a realistic Chrome User-Agent string for scripted HTTP requests. Two modes:

Under Chrome's reduced-UA policy, only the major version segment actually changes — the rest of the UA string is frozen per platform. This script emits what real Chrome would send.

Quick start

$ chrome-ua
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36

Use it with curl to mimic real Chrome:

curl -A "$(chrome-ua)" https://example.com

Common examples

Get the latest Chrome version without a local install — useful on Linux, in CI, or when your installed Chrome is stale:

curl -A "$(chrome-ua --latest)" https://example.com

Emit a Windows Chrome UA from your Mac — matches Chrome's actual UA on Windows, not what you'd see in a Mac browser:

$ chrome-ua --platform win
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36

Fetch the latest Linux Chrome UA:

$ chrome-ua --latest --platform linux
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36

Point at a specific Chrome install (e.g. Canary, Beta, or a non-standard path):

chrome-ua --app "/Applications/Google Chrome Canary.app"

Pipe from the web (since this is published at toolio.sh):

curl -A "$(curl -s https://toolio.sh/chrome-ua | bash)" https://example.com

Local vs latest: which should you use?

Both modes honor Chrome's reduced-UA policy — the platform string is frozen per-OS regardless of the actual machine. --platform lets you override which platform shape is emitted.

Fallback behavior

The default (local) mode has a three-step fallback chain:

  1. Read local Chrome via defaults read Chrome.app/Contents/Info.plist — this is the happy path on macOS.
  2. Auto network fallback — if the local read fails (Chrome not installed, non-macOS host, permissions, unreadable plist) and curl + jq are available, the script silently fetches the latest major from Google's API. Warns to stderr that it did so.
  3. Pinned fallback – if the local read failed and the network fetch failed (no curl, no network, API broken), the script uses a hardcoded FALLBACK_MAJOR constant and warns to stderr. The constant is set in the script source (FALLBACK_MAJOR=) and needs periodic refreshing.

The explicit --latest mode skips step 1 entirely — it goes straight to step 2, then falls back to step 3 if that fails.

This means curl -A "$(chrome-ua)" ... is always usable; it will always emit some plausible UA, even on a fresh Linux container with no Chrome.

Disabling the automatic network fallback

Set CHROME_UA_OFFLINE=1 (or any non-empty value) to block the automatic network fallback. When this is set:


Reference

All options

Flag Description
-l, --latest Fetch the latest stable Chrome major version from Google's Version History API
-p, --platform mac|win|linux UA shape (and, with --latest, the API path). Default: mac
-a, --app PATH Path to Chrome.app for local mode (default: /Applications/Google Chrome.app)
-h, --help Display help

Environment variables

Variable Meaning
CHROME_UA_OFFLINE If set (any non-empty value), disables the automatic network fallback when local read fails. Does not affect explicit --latest.

Exit codes

Code Meaning
0 Success (always, when flags are valid — the script always emits some UA, falling back to a pinned version with a warning if all else fails)
2 Usage error (unknown flag, missing --app/--platform value, invalid --platform)

Dependencies

Caveats