Tools
Guides

User-Agent Parser

Dev

Parse a User-Agent string into browser, engine, operating system and device type. Heuristic, fully client-side.

100% client-side No backend
User-Agent string
Output
Browser
Engine
Operating system
Device type
Bot / crawler
On this page

What is a User-Agent parser?#

The User-Agent (UA) string is the line of text every browser and HTTP client appends to its requests to describe itself. It is also a famously unstructured mess: vendors stack historical compatibility tokens on top of each other, so a single modern Chrome string also contains the words Mozilla, AppleWebKit, KHTML, Gecko, and Safari — none of which mean the browser is actually any of those things. Reading a raw UA by eye is slow and error-prone, which is why almost every analytics dashboard, access-log tool, and bot-detection layer runs it through a parser first.

This page takes any UA string and breaks it into the five facts you actually want: browser (name and version), engine (the rendering core), OS (operating system and version), device type (desktop, mobile, or tablet), and isBot (whether the string looks like a crawler). It runs entirely in your browser — paste a string from a log line and read the breakdown, with no server round-trip.

The reason browser detection is harder than it looks is ordering. Specialised browsers must be checked before Chrome, because their UA strings all contain the literal token Chrome for compatibility. Microsoft Edge, Opera, Samsung Internet, Vivaldi and CocCoc would all be misreported as Chrome by a naive if (ua.includes("chrome")) check. The same is true of engines: the string AppleWebKit appears in both Blink browsers (Chrome, Edge, Opera) and pure WebKit ones (Safari), so the engine is inferred from the browser family, not matched directly.

How to use it#

  1. Click Use current at the top to load this browser’s own navigator.userAgent into the input box — the fastest way to see what your own traffic looks like.
  2. Or paste any UA string into the input pane — from an nginx access log, a req.headers["user-agent"] in your backend, a curl request, anything.
  3. Read the five rows in the output pane:
    • Browser — family name and major version (e.g. Chrome 120).
    • Engine — the rendering engine (Blink, WebKit, Gecko, Trident).
    • OS — operating system and version where recoverable (e.g. Windows 10/11, iOS 17, Android 14).
    • Devicedesktop, mobile, or tablet, inferred from tokens like iPad, Android without Mobile, iPhone.
    • Botyes / no, flagged by matching against crawler identifiers (bot, crawl, spider, slurp, pingdom, headless, phantomjs, curl, wget, python-requests, axios, …).
  4. Click Clear to empty both panes.
  5. The status line summarises the result or reports that the input was empty.

Key features#

  • Speciality-first browser detection. Edge, Opera, Samsung Internet, Vivaldi, CocCoc and Firefox are all matched before Chrome and Safari, so they are not silently swallowed by the Chrome compatibility token.
  • Engine inferred from the family. Blink versus WebKit is decided by the detected browser, not by a fragile direct match on AppleWebKit — which is why a Safari string is not reported as Chrome.
  • Device-type classification. Tablets are told apart from phones using the iPad token and the Android ... Mobile distinction, the same heuristics analytics tools rely on.
  • Crawler flag. The Bot row flags the strings you usually want to exclude from human-facing metrics — search crawlers, uptime monitors, headless browsers, and HTTP libraries.
  • 100% client-side. No UA is ever sent anywhere. That also means you can paste tokens from production logs without leaking them to a third-party parsing API.

Worked example#

Paste this typical Chrome-on-Windows string from an access log:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

and the five rows fill in as:

Browser   Chrome 120
Engine    Blink
OS        Windows 10/11
Device    desktop
Bot       no

Now contrast it with an Edge string — note the trailing Edg/120:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0

A naive parser that checks Chrome first reports Chrome 120 here — wrong. This page checks Edg/ before Chrome/, so the same string correctly yields Browser: Microsoft Edge 120, with the engine still Blink (Edge is Chromium-based).

A third case shows the bot path. A health-check script sending curl/7.81.0 is flagged Bot: yes even though it carries no Mozilla wrapper, because curl is one of the library tokens the bot matcher scans for. That is the row that lets you separate real-user traffic from automated noise when you are eyeballing a log.

FAQ#

Why does my Edge browser report as “Microsoft Edge” and not “Chrome”, even though the UA contains the word Chrome?#

Because Edge’s UA deliberately includes Chrome/120.0.0.0 so that websites built to serve Chrome will serve Edge too. This parser tests the Edg/ token first, then Chrome/, so the specialised family wins. Any parser that does not order its checks this way will misreport every Chromium derivative as Chrome.

Can I trust the OS version from a UA string?#

Up to a point. Windows collapses 10 and 11 into Windows NT 10.0, so they are reported as 10/11 here. iOS and macOS versions are recoverable from the OS X_x_x token but historically get frozen at release time. Treat the version as a strong hint, not a guarantee, and do not gate security decisions on it.

Is the Bot flag reliable enough to block traffic?#

No — UA-based bot detection is a convenience for log analysis and dashboard filtering, not a security boundary. Malicious clients forge whatever UA they like, including perfectly human-looking ones. Use this row to spot the obvious crawlers and libraries; use rate limiting, authentication, and behavioural checks for anything that actually needs to be trustworthy.

The parser shows “Unknown” for everything. What did I paste?#

Either an empty/whitespace string, or a UA from a client this parser does not recognise (some desktop apps and SDKs send bespoke identifiers). The status line will say the input was empty in the first case; in the second, the browser and OS simply fall through to Unknown while device type defaults to desktop. The raw string is preserved in the input pane so you can inspect it.