How to Read a User Agent String, Token by Token
Open any server log and you will find lines like โMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36โ. It names at least four browsers, yet it came from just one. User agent strings are a fossil record of the browser wars, and reading them correctly matters for analytics, bug reports and responsive layouts. Here is how to decode one, piece by piece.
The anatomy of a modern string
Take the Chrome-on-Windows example above and split it into tokens:
Mozilla/5.0โ a historical compatibility token sent by virtually every browser today.(Windows NT 10.0; Win64; x64)โ the platform: operating system, architecture and sometimes device.AppleWebKit/537.36โ the rendering engine family. Chromeโs Blink engine was forked from WebKit and kept the token.(KHTML, like Gecko)โ more compatibility history, pointing at the KDE engine WebKit grew out of and the Gecko engine of Firefox.Chrome/120.0.0.0โ the actual browser and version.Safari/537.36โ appended so sites that looked for Safari would serve the full experience.
Why every browser pretends to be another
In the 1990s, sites sniffed for โMozillaโ โ the code name of Netscape Navigator โ and sent advanced pages only to it. Rival browsers started adding โMozillaโ to their own strings so they would not get the basic version. Each new engine repeated the trick: WebKit claimed to be โlike Geckoโ, Chrome added โSafariโ, and Edge adds its own Edg/ token after the Chrome string.
The lesson for developers: never check for a single word. Edge contains โChromeโ, and Chrome contains โSafariโ, so the order of your checks decides the answer.
Platform clues and frozen values
The parenthesized part often holds the most useful information, but it has become less precise over time:
- Windows 11 still reports
Windows NT 10.0, so the string cannot tell it from Windows 10. - Recent macOS versions report a frozen
Intel Mac OS X 10_15_7even on Apple silicon. - Chromium-based browsers have reduced the details they send, often replacing minor version numbers with zeros.
- Mobile strings usually include
Mobile, which is the traditional signal for a phone layout.
For precise data, modern Chromium browsers offer User-Agent Client Hints, a set of headers the server can request explicitly. Treat the classic string as a hint, not a fact.
How to build a test set with the generator
Parsers, analytics pipelines and device-detection code need a variety of inputs. The generator above makes that quick:
- Use the Device option to choose any mix, desktop only or mobile only.
- Generate up to 50 strings at once. Each is complete and correctly structured, with plausible versions and device names.
- Read the label in parentheses at the end โ for example โChrome ยท Androidโ โ to see what each string represents.
- Remove that label before pasting a string into a request header or a fixture file.
- Export the batch as JSON or CSV to drive table-based tests.
The strings are realistic combinations rather than records of specific releases, which is ideal for testing structure and branching logic.
Prefer feature detection
If your goal is to decide whether a browser can do something, test for the feature itself rather than reading the user agent. A check such as 'share' in navigator stays correct when a new browser appears, while UA rules quietly rot. Reserve UA parsing for analytics, logging and support diagnostics.
Mobile strings: what changes
A typical phone string looks different in the parentheses. Chrome on Android includes Linux; Android plus a version and often a device model, then adds Mobile before the Safari token. Safari on iPhone reports something like iPhone; CPU iPhone OS with an underscore-separated version, and its own Version/ and Mobile/ tokens. Tablets frequently leave out the word Mobile, which is why some sites show tablets the desktop layout.
When you test responsive behavior, combine a range of mobile and desktop strings with real screen sizes, because many layouts depend on viewport width rather than the user agent.
Pro tips
- Log the full user agent string in bug reports โ it saves a round of questions.
- Check for Edge before Chrome and Chrome before Safari when parsing.
- Keep a fixed set of test strings in your repository so parser changes are easy to verify.
- Never block users based on the user agent alone; it is trivial to change.
Frequently asked questions
Why do all user agents start with Mozilla/5.0?
It is a compatibility leftover from the 1990s, when sites served rich pages only to browsers that identified as Mozilla. Removing it now could break old sniffing code.
Can a user agent be faked?
Yes. Browser developer tools, extensions and any HTTP client can send whatever string they like, so it should never be used for security decisions.
What are User-Agent Client Hints?
They are request headers, such as Sec-CH-UA, that let a server ask Chromium-based browsers for specific details like platform or full version instead of parsing one long string.