User-Agent Client Hints and On-Demand Metadata in Chromium
This article explores User-Agent Client Hints (UA-CH), a modern web standard designed to replace the traditional User-Agent string. It explains what these hints are, why they were introduced to improve user privacy, and the exact mechanisms the Chromium web browser uses to deliver specific device and browser metadata to servers and web applications strictly on an on-demand basis.
What Are User-Agent Client Hints?
User-Agent Client Hints (UA-CH) are a set of HTTP request headers and a JavaScript API that allow web browsers to share information about the user's device, operating system, and browser with a web server.
Historically, browsers sent a monolithic User-Agent (UA) string with every single HTTP request. This string broadcasted detailed system data—such as exact OS versions and phone models—to every website visited. While useful for tailoring content to specific devices, the legacy UA string created two major problems:
- Privacy Vulnerabilities: It enabled passive browser fingerprinting, allowing trackers to uniquely identify users across the web without their consent.
- Parsing Complexity: The string grew overly complex and spoofed over decades, causing frequent bugs when developers tried to parse it.
UA-CH solves these issues by replacing the complex UA string with structured, standardized data points that are largely withheld unless a server explicitly asks for them.
Default vs. On-Demand Data in Chromium
To balance functionality with privacy, Chromium divides User-Agent metadata into two categories: low-entropy (basic) and high-entropy (detailed) hints.
Low-Entropy Hints (Sent by Default) With every HTTP request, Chromium automatically sends three basic headers. These do not reveal enough information to fingerprint a user, but they give servers enough context for basic content negotiation:
Sec-CH-UA: The browser brand and its major version number.Sec-CH-UA-Mobile: A boolean (?1or?0) indicating if the browser is on a mobile device.Sec-CH-UA-Platform: The broad operating system (e.g., "Windows", "macOS", "Android").
High-Entropy Hints (Delivered On Demand) Detailed information that could be used to identify an individual user is classified as high-entropy. Chromium withholds this data by default. Examples include:
Sec-CH-UA-Platform-Version: The exact OS version.Sec-CH-UA-Model: The specific hardware model (e.g., "Pixel 7").Sec-CH-UA-Arch: The underlying CPU architecture (e.g., "x86" or "arm").Sec-CH-UA-Full-Version-List: The full version numbers of the browser rather than just the major version.
How Chromium Delivers Metadata On Demand
Chromium provides two methods for websites to request high-entropy device metadata on demand: via HTTP headers for server-side adaptation, and via a JavaScript API for client-side logic.
1. The HTTP Header Mechanism
For a server to receive high-entropy hints, a negotiation must take place between the server and the Chromium browser:
- Step 1 (The Opt-In): When a user visits a website,
the server responds to the initial request with an
Accept-CHheader. This header contains a comma-separated list of the exact metadata the server wants. For example:Accept-CH: Sec-CH-UA-Model, Sec-CH-UA-Platform-Version. - Step 2 (The Delivery): Chromium reads the
Accept-CHheader and remembers this preference for the duration of the session. On all subsequent requests to that specific website, Chromium attaches the requestedSec-CH-UA-ModelandSec-CH-UA-Platform-Versionheaders.
If a server requires this data on the very first page load to render
the page correctly, it can also send a Critical-CH header.
This instructs Chromium to immediately retry the initial request with
the newly requested hints attached.
2. The JavaScript API Mechanism
Web applications often need device metadata dynamically via scripts
rather than during the initial server request. Chromium facilitates this
through the navigator.userAgentData API.
- Accessing Default Data: Scripts can read
low-entropy data synchronously by calling properties like
navigator.userAgentData.mobileornavigator.userAgentData.platform. - Requesting On-Demand Data: To get high-entropy
data, the script must call the
navigator.userAgentData.getHighEntropyValues()method and pass an array of the specific hints it needs (e.g.,['model', 'architecture', 'bitness']).
Because this method is asynchronous and returns a JavaScript Promise, it gives Chromium a control point. Before resolving the Promise and handing over the sensitive metadata, Chromium can audit the request, log it for security purposes, or apply user-defined privacy blocks.