TL;DR
A user agent is the program acting for you on the web, which almost always means your browser. With every request, it sends a line of text called the user agent string that names the browser, its version and your operating system. Sites use it for statistics, support and, less wisely, for deciding what to show you.
In this guide
What is a user agent string?
A user agent string is the value of the User-Agent header that a browser sends with every request, and the same text JavaScript reads from navigator.userAgent. It names the browser, its rendering engine and the operating system it's running on, in a format that grew by accident over thirty years and now mostly exists for compatibility.
Here's the one Chrome 155 sends from a Mac:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36
It mentions four browsers and two engines that aren't Chrome. That's normal.
How to read a user agent string
Read it left to right as a list of products, each one a name, a slash and a version, with comments in brackets. Most of the tokens are fossils from the browser wars that every browser keeps sending so old sites don't lock them out. Only one or two parts actually identify the browser.
| Part | What it claims | What it really tells you |
|---|---|---|
Mozilla/5.0 | A Mozilla-compatible browser | Nothing. Almost every browser sends it, for historical reasons |
(Macintosh; Intel Mac OS X 10_15_7) | An Intel Mac on macOS 10.15.7 | A Mac. Chrome sends this fixed value whatever the chip or macOS version |
AppleWebKit/537.36 | Apple's WebKit engine | Chrome's engine was forked from WebKit, and the number stopped moving long ago |
(KHTML, like Gecko) | KDE's engine, behaving like Firefox's | Nothing. Another compatibility fossil |
Chrome/155.0.0.0 | Chrome, version 155 | The real browser and its major version. The zeros are deliberate |
Safari/537.36 | Safari | Nothing. It's there so sites that check for Safari let Chrome in |
The rule I use is to read from the right. Browsers add their own name at the end, so the last product token is usually the honest one. Edge sends the same string as Chrome with Edg/155.0.0.0 on the end. Firefox's is shorter and ends in Firefox/ and a version, after a Gecko/20100101 that has been frozen at that date for years.
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:158.0) Gecko/20100101 Firefox/158.0
Why the user agent is unreliable for browser detection
A user agent string is a claim the browser makes, not a fact you can check. People change it with an extension or a developer tools setting, browsers fake parts of it on purpose, and the version numbers that would make it useful have been frozen. Treat it as a hint for logs and support, never as the thing that decides which code runs.
Some of the lying is built in. Windows 11 still reports Windows NT 10.0, and Microsoft has said the string won't be updated to tell the two apart. That Mac string above is the same on a brand-new Apple Silicon machine as on a 2019 Intel one. Every browser claims to be Mozilla, Chrome claims to be Safari, and Edge claims to be Chrome.
Then there's the code people write on top of it. Before Chrome reached version 100 in 2022, Google spent months warning that user agent parsers expecting a two-digit version would break, and handed developers a flag to test their sites against it. Nothing about the browser had changed except one number, and that was enough to break the parsers. If you need to know whether a browser can do something, check for the feature itself ('share' in navigator, CSS.supports(...)) and let the user agent go back to being a label. Apple's Safari documentation says the same thing.
What is user-agent reduction?
User-agent reduction is Chrome's change, now complete, that cut the user agent string down to a fixed shape: the browser's major version, a frozen operating system value and zeros for the minor version. The aim was to make the string less useful for fingerprinting people. The details moved to Client Hints, which sites have to ask for.
It happened in stages. Chrome 101 replaced the minor version with zeros. Chrome 107 froze the desktop operating system and CPU details to one value per platform, which is why every Mac running Chrome reports Intel Mac OS X 10_15_7 and every Windows PC reports Windows NT 10.0; Win64; x64. Chrome 110 started doing the same on Android, where the string now says Android 10; K whatever the phone is. Google's own documentation now describes the reduction as complete, and it covers what JavaScript sees in navigator.userAgent, navigator.appVersion and navigator.platform as well as the header.
User-Agent Client Hints
Client Hints are the replacement. By default Chrome and Edge send three extra headers with every HTTPS request: Sec-CH-UA (brands and major version), Sec-CH-UA-Mobile and Sec-CH-UA-Platform. Anything more specific, like the full version, the operating system version or the device model, has to be requested. A server asks with an Accept-CH response header, and a page asks from JavaScript:
const data = await navigator.userAgentData?.getHighEntropyValues([ "platformVersion", "fullVersionList", "model",]);console.log(data ?? navigator.userAgent);
That's the way to tell Windows 11 from Windows 10: a platformVersion starting at 13 or above is Windows 11. Two caveats keep this from being a clean replacement. Client Hints only exist in Chromium browsers, and as of October 2026 neither Firefox nor Safari supports them. And the browser decides what to hand back, so a high-entropy value can still come back empty.
For support teams
The user agent your customer copies for you is a good start, and it will tell you the browser and its major version. It won't tell you the exact Chrome build, whether they're on Windows 10 or 11, or which Mac they own. If those matter for the bug, ask for them directly, or send them to the Browser info tool, which collects the details a support reply usually needs and copies them in one go.
More on Browser and device