How Client Hints Replace User-Agent Strings
User-Agent Client Hints (UA-CH) replace the traditional, monolithic User-Agent (UA) string with a privacy-focused, structured mechanism for sharing browser and device data. Instead of automatically broadcasting detailed system information on every HTTP request, Client Hints separate data into low-entropy (basic) and high-entropy (detailed) categories. This architecture allows web servers and JavaScript APIs to selectively request only the specific device characteristics they need, reducing passive browser fingerprinting while maintaining necessary developer functionality.
The Shift Away from the Legacy User-Agent String
The legacy User-Agent string included the browser name,
rendering engine, operating system version, and device type in a single
plain-text header. Because browsers broadcast this complete string with
every network request, trackers could easily correlate user sessions
across the web without user consent. Major browsers have responded by
“freezing” or reducing the legacy UA string, populating it with generic
values, and introducing User-Agent Client Hints as the standard
replacement.
How Servers Read Client Hints
On the server side, data exchange moves from an all-in-one broadcast model to an explicit request-and-response negotiation:
Default Low-Entropy Headers: By default, browsers send only basic, non-identifying headers with initial HTTPS requests. These typically include:
Sec-CH-UA: The browser brand and significant version (e.g.,"Chromium";v="120").Sec-CH-UA-Mobile: A boolean flag indicating if the request comes from a mobile device (?0or?1).Sec-CH-UA-Platform: The operating system family (e.g.,"Windows"or"Android").
Requesting High-Entropy Headers: If a server requires deeper data (such as the exact OS version, device model, or architecture), it must explicitly request it by returning the
Accept-CHresponse header:Accept-CH: Sec-CH-UA-Model, Sec-CH-UA-Platform-Version, Sec-CH-UA-ArchSubsequent Transmissions: Upon receiving this header over a secure HTTPS connection, the browser sends the requested high-entropy headers on subsequent requests to that origin:
Sec-CH-UA-Model: "Pixel 7" Sec-CH-UA-Platform-Version: "14.0.0" Sec-CH-UA-Arch: "arm"
How JavaScript Reads Client Hints
On the client side, the legacy navigator.userAgent
string property is replaced by the navigator.userAgentData
object.
Synchronous Low-Entropy Access: Developers can instantly read basic properties without performance penalties:
const brands = navigator.userAgentData.brands; const isMobile = navigator.userAgentData.mobile; const platform = navigator.userAgentData.platform;Asynchronous High-Entropy Access: To access detailed device metrics, JavaScript must invoke the asynchronous
getHighEntropyValues()method, passing an array of the required hint keys:navigator.userAgentData.getHighEntropyValues([ "architecture", "model", "platformVersion", "fullVersionList" ]).then(hints => { console.log(hints.model); console.log(hints.platformVersion); });
Because high-entropy retrieval is asynchronous, the browser can enforce privacy budgets, evaluate permissions, or log access to sensitive hardware information before returning the data.
Summary of Advantages
- Privacy Preservation: Detailed device characteristics are only shared when explicitly requested.
- Structured Data: Headers and API responses use structured dictionaries and lists, eliminating the need for complex regular expressions to parse messy strings.
- Auditing and Control: Browser vendors and site owners can monitor which third-party scripts or origins request access to fingerprintable data.