UserAgent
Turn the cryptic user-agent string into structured facts - browser, engine, OS and device - and tap the modern User-Agent Client Hints API where the browser offers it.
@inject Bit.Butil.UserAgent userAgentMDN reference
Parses a user-agent string into a UserAgentProperties object with the browser name and version, layout engine, manufacturer, product and operating system details. With no argument it parses the current browser's own string.
UserAgentProperties props = await userAgent.Extract();
Console.WriteLine(props.Name); // "Chrome"
Console.WriteLine(props.Version); // "126.0.0.0"
Console.WriteLine(props.Layout); // "Blink"
Console.WriteLine(props.OsName); // "Windows"
Console.WriteLine(props.OsVersion); // "10" - Windows 11 still says NT 10.0
// or analyze any string, e.g. one captured from a server log:
var other = await userAgent.Extract("Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 ...)");User-Agent Client Hints (navigator.userAgentData) are the privacy-friendly successor to UA-string sniffing. These low-entropy reads are available without any prompt on supporting browsers.
bool supported = await userAgent.IsClientHintsSupported();
string platform = await userAgent.GetPlatform(); // "Windows", "" when unsupported
bool mobile = await userAgent.IsMobile();The low-entropy brand list identifies the browser and its engine family without revealing precise versions. Browsers without Client Hints return an empty array.
UserAgentBrand[] brands = await userAgent.GetBrands();
foreach (var brand in brands)
{
Console.WriteLine($"{brand.Brand} {brand.Version}");
}Detailed facts such as CPU architecture, exact platform version and device model must be requested hint by hint; the browser may decline any of them, so every property of the result is nullable.
HighEntropyUserAgent values = await userAgent.GetHighEntropyValues(
"architecture", "bitness", "model", "platformVersion", "fullVersionList");
Console.WriteLine(values.Architecture); // "x86"
Console.WriteLine(values.Bitness); // "64"
Console.WriteLine(values.PlatformVersion); // "15.0.0"navigator.userAgentData currently ships in Chromium-based browsers only; Firefox and Safari
report it as unsupported. Always check IsClientHintsSupported first and fall back to
Extract, which works everywhere because it parses the classic user-agent string.
API reference
ValueTask<UserAgentProperties> Extract(string? userAgentString = null)ValueTask<bool> IsClientHintsSupported()ValueTask<UserAgentBrand[]> GetBrands()ValueTask<bool> IsMobile()ValueTask<string> GetPlatform()ValueTask<HighEntropyUserAgent> GetHighEntropyValues(params string[] hints)