What Is My User Agent? The User-Agent String Explained Part by Part

Every HTTP request from a browser carries a `User-Agent` header, a single line that is supposed to say which software sent the request. In practice it is a record of thirty years of browsers pretending to be each other. It contains names of browsers you are not using, engines that no longer exist and, since 2022, version numbers Chrome deliberately rounds to zero. Here is how to read one and what it can still tell you.

What is my user agent?

Your browser sends its user agent with every page request, and scripts can read it too. The quickest way to see yours is to open the browser console (F12, then Console) and run one line.

navigator.userAgent
// "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
//  Chrome/140.0.0.0 Safari/537.36"

// Chromium browsers only: structured data
navigator.userAgentData?.brands
navigator.userAgentData?.platform     // "Windows"
navigator.userAgentData?.mobile       // false
# What a command-line client sends
curl -s https://httpbin.org/user-agent
# {"user-agent": "curl/8.7.1"}

The value can differ from what a server receives if an extension, a proxy or the browser's device emulation changes it. To see exactly what arrives, look at the request headers in the browser's Network tab, or log req.headers['user-agent'] on the server.

Reading a Chrome user-agent string, token by token

Mozilla/5.0                     legacy token, sent by virtually every browser
(Windows NT 10.0; Win64; x64)   platform: OS and architecture
AppleWebKit/537.36              engine lineage (Chrome's Blink forked from WebKit)
(KHTML, like Gecko)             more compatibility claims
Chrome/140.0.0.0                the actual browser and major version
Safari/537.36                   compatibility with sites sniffing for Safari

Only two parts carry real information here: the platform in the first parentheses and the Chrome/140 major version. Everything else exists so that old server-side sniffing code keeps serving modern pages.

Other browsers follow the same pattern with different final tokens. Edge appends Edg/140.0.0.0, Opera appends OPR/…, and Samsung Internet adds SamsungBrowser/…. Firefox is the most honest of the major browsers: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0, where Gecko/20100101 is a frozen constant, not a build date.

Why every browser claims to be Mozilla

In the mid-1990s, Netscape Navigator (code name Mozilla) supported frames and other features that Internet Explorer did not yet have. Sites checked for Mozilla in the user agent and sent the good version only to Netscape. Internet Explorer responded by calling itself Mozilla/4.0 (compatible; MSIE …), and every later browser inherited the trick.

The same thing happened again with each engine. KHTML-based Konqueror added like Gecko. Apple's WebKit, forked from KHTML, kept that phrase. Chrome started on WebKit and added Safari/ so that sites sniffing for Safari would work. Each new browser appended the names that sites were checking for, which is why a 2026 Chrome string still mentions four other browsers.

The lesson for your own code is the one browsers learned: servers that branch on the user-agent string end up forcing every newcomer to lie. That is why feature detection is preferred.

User-agent reduction: what Chrome froze

From 2022 Chrome began reducing the information in the string, to cut down passive fingerprinting. The reduced string keeps the browser brand, the major version, whether the device is mobile, and the platform. It freezes the rest:

minor/build version   Chrome/140.0.0.0        (always .0.0.0)
Windows version       Windows NT 10.0         (also on Windows 11)
macOS version         Mac OS X 10_15_7        (frozen, whatever the real version)
Android version+model Linux; Android 10; K    (fixed values, no device model)

Safari already froze its macOS version at 10_15_7, and Firefox reports Windows NT 10.0 on Windows 11 as well. A user agent therefore cannot tell you whether a visitor runs Windows 10 or 11, which exact macOS release they have, or which phone model they own. Code and analytics that relied on those fields now read constants.

iPads add another twist. Since iPadOS 13, Safari on an iPad requests desktop sites by default and sends a Macintosh user agent. Touch support (navigator.maxTouchPoints > 1) is the usual way to tell an iPad from a Mac.

User-Agent Client Hints

Chromium browsers replace the lost detail with Client Hints: separate, structured request headers. Three low-entropy hints are sent on every request by default:

Sec-CH-UA: "Chromium";v="140", "Google Chrome";v="140", "Not;A=Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "Windows"

The odd Not;A=Brand entry is deliberate GREASE: a random fake brand that forces parsers to handle unknown values instead of matching the list exactly. More detailed hints, such as the full version list, platform version, device model and architecture, are only sent if the server asks for them with Accept-CH, or read in JavaScript with getHighEntropyValues().

HTTP/1.1 200 OK
Accept-CH: Sec-CH-UA-Platform-Version, Sec-CH-UA-Model

// or in the page
const ua = await navigator.userAgentData.getHighEntropyValues(
  ['platformVersion', 'model', 'fullVersionList']
);
// On Windows, platformVersion 13.0.0 or higher means Windows 11

Firefox and Safari do not implement User-Agent Client Hints, so any logic built on them needs a fallback to the classic string.

What a user agent is good for, and what it is not

It is useful for analytics breakdowns by browser family and major version, for spotting declared bots such as Googlebot or bingbot, for debugging a bug that only one browser reports, and for choosing a download for the visitor's operating system.

It is not reliable for security decisions or capability checks. The header is set by the client, and anyone can send any value: curl -A 'Googlebot/2.1' is enough to impersonate Google. Verify crawlers the way the search engines document, with a reverse DNS lookup followed by a forward lookup. To decide whether a feature is available, test for the feature in JavaScript ('share' in navigator) or in CSS (@supports), not the browser name.

For privacy it cuts both ways. A user agent alone identifies software, not a person, but combined with screen size, timezone and fonts it contributes to fingerprinting. That is the reason for the reduction.

Sources and further reading

RFC 9110, section 10.1.5, defines the User-Agent header. The Chrome team's documentation on User-Agent reduction and the WICG User-Agent Client Hints specification describe the frozen values and the Sec-CH-UA headers. MDN documents navigator.userAgent and NavigatorUAData. Microsoft's documentation explains detecting Windows 11 through Sec-CH-UA-Platform-Version.

Frequently asked questions

What is my user agent?

Open the browser console and run `navigator.userAgent` to see the string your browser sends. The Network tab in developer tools shows the exact `User-Agent` request header, including any changes made by extensions or device emulation.

Why do all user agents start with Mozilla/5.0?

For compatibility. In the 1990s sites served advanced pages only to Netscape (Mozilla), so other browsers started claiming to be Mozilla too. The token no longer means anything, but removing it would break old sniffing code.

Why does my user agent say Windows NT 10.0 on Windows 11?

Browsers froze the Windows version in the string. To detect Windows 11 in Chromium browsers, request the `Sec-CH-UA-Platform-Version` client hint; a value of 13 or higher means Windows 11.

Can the user-agent string be faked?

Yes, trivially. Browser settings, extensions and any HTTP client can send any value. Never use it for authentication or security, and verify search engine crawlers with reverse and forward DNS.

What are User-Agent Client Hints?

Structured headers such as `Sec-CH-UA`, `Sec-CH-UA-Mobile` and `Sec-CH-UA-Platform` that Chromium browsers send instead of detailed user-agent data. Extra details are sent only when the server requests them with `Accept-CH`.

Why does Chrome's version always end in .0.0.0?

Since the user-agent reduction, Chrome only exposes its major version in the string and sends zeros for the rest. The full version is available through the `Sec-CH-UA-Full-Version-List` hint when requested.