What Is a User Agent String?

If you have ever seen your user-agent string, your first reaction was probably confusion. Why does Chrome claim to be Mozilla, Safari and Gecko all at once? The answer is thirty years of web history frozen into a single line of text — and understanding it explains why it is such an unreliable way to identify a browser.
Anatomy of the string
A typical user agent reads something like "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36". It is a space-separated list of product tokens. In principle it names the browser, its rendering engine and the operating system, and a server or a page can read it to decide what to send.
The trouble is that almost every token is a historical courtesy rather than the truth. "Mozilla/5.0" is there because 1990s servers checked for "Mozilla" before serving modern pages, so every browser started claiming it. "KHTML, like Gecko" and the trailing "Safari" exist so sites written for older engines would not lock newer browsers out. The string is less a fact sheet than a costume assembled to avoid being turned away.
Two copies of the same claim
The user agent exists in two places at once. It is an HTTP request header, sent with the page request and again with every image, script, stylesheet and font that page pulls in, so a single visit can transmit it dozens of times. It is also readable from JavaScript as navigator.userAgent, which is what a page inspects client-side. Normally the two agree, but they can diverge — an extension or a developer-tools device override may rewrite one and leave the other alone, a small reminder that neither is an authoritative source.
Servers lean on the header for several jobs at once: choosing between a desktop and a mobile build, deciding whether to serve a legacy bundle, filtering out crawlers, and filling analytics dashboards. That accumulated dependency is precisely why the format can never be tidied up. A browser that removed a misleading token would immediately be misidentified by thousands of sites still pattern-matching on it, so the old tokens stay and new ones are appended on the end.
Why you cannot trust it
Because the user agent is just a text header, anything can send anything. Users spoof it with one browser setting, developer tools let you impersonate any device in a click, and bots routinely disguise themselves as ordinary browsers. Even honestly, it lies by omission: a Chromium-based browser like Edge, Brave or Opera can look almost identical to Chrome in the string.
That is why serious code avoids sniffing the user agent to decide what a browser can do. The robust approach is feature detection: test directly whether the API you need exists, which is exactly what the Feature Support panel does. The user agent is a useful label for a bug report, not a dependable basis for logic.
The slow move to Client Hints
Because the string is both unreliable and a fingerprinting risk, browsers are freezing and reducing it. Modern Chrome now sends a deliberately vague user agent and offers the real details through User-Agent Client Hints — a system where a site must explicitly ask for specific facts, such as the platform version, rather than receiving everything by default. Safari and Firefox have trimmed their strings for similar privacy reasons.
DeviceScope parses whatever your browser sends entirely on your device — no third-party library, no upload — and names the browser, engine and OS as best the string allows. Where a browser has hidden a detail, it is reported honestly as unknown rather than guessed.
What UA reduction actually froze
The reduction did not delete the string; it pinned most of it to constants. The browser version now carries a real major number with the rest fixed at 0.0.0, so "Chrome/120.0.0.0" says nothing about the exact build. The desktop platform version is frozen too: every Windows 10 and Windows 11 machine reports "Windows NT 10.0", and macOS reports a fixed 10_15_7 whichever release you are actually running. On Android the device model and OS version are replaced by the placeholders "Android 10; K". What survives is the coarse distinction layout genuinely needs — which platform you are on, and whether it is mobile.
The detail moves to Client Hints, split across two tiers. The low-entropy hints — Sec-CH-UA with its brand list, Sec-CH-UA-Mobile and Sec-CH-UA-Platform — are sent automatically, because they reveal little on their own. The high-entropy ones, such as the full platform version, the CPU architecture, the device model and the full version list, are withheld until a site asks for them explicitly through an Accept-CH response header or calls navigator.userAgentData.getHighEntropyValues() in JavaScript. That request is visible and attributable, which is the whole point. Client Hints are a Chromium feature; Safari and Firefox have not adopted them, so on those browsers the reduced string is all there is.
The takeaway
The user-agent string is a costume stitched together from decades of compatibility hacks, easily spoofed and now being replaced by Client Hints. Read yours on the Browser & System panel, but for deciding what a browser can do, prefer the direct tests on the Feature Support panel.
How your browser identifies itself, with a copy-ready health summary.
More guides

What Your Browser Reveals About You (and What It Doesn't)
A web page can read a surprising amount about your setup with no permission at all — and there are hard limits it cannot cross. Here is exactly where the line sits.

Screen Resolution, DPR and Retina Displays Explained
Why the resolution your browser reports may not match the pixels in the panel, what device pixel ratio really means, and why "Retina" is just marketing for a number you can read yourself.

WebGL, WebGPU and Hardware Acceleration
How the browser hands work to your graphics card, why the GPU name often looks scrambled, and what the newer WebGPU standard changes.