Sec-CH-UA Client Hints

User-Agent Client Hints parser. Browsers replacing the freeform User-Agent string send a family of Sec-CH-UA-* request headers carrying structured-fields data per RFC 8941:

Sec-CH-UA: "Chromium";v="124", "Not-A.Brand";v="99", "Google Chrome";v="124" Sec-CH-UA-Mobile: ?0 Sec-CH-UA-Platform: "Windows" Sec-CH-UA-Platform-Version: "15.0.0" Sec-CH-UA-Arch: "x86" Sec-CH-UA-Bitness: "64" Sec-CH-UA-Model: "" Sec-CH-UA-Full-Version-List: "Chromium";v="124.0.6367.91", ... Sec-CH-UA-WoW64: ?0 Sec-CH-UA-Form-Factors: "Desktop"

parse(headers) walks an HTTP request's headers map and returns a normalized object — brand list with versions, mobile boolean, platform / platform-version / arch / bitness / model / form- factors strings — plus the raw RFC 8941 parsed shape for any header the operator wants to inspect verbatim.

Operators use it to: - Replace freeform UA-string parsing (deprecated; brittle). - Negotiate per-platform CSS / JS bundles (Sec-CH-UA-Platform). - Detect mobile-class clients without UA-sniffing. - Audit fingerprinting-style header negotiation.

The primitive treats every header as defensive request-shape input — returns null for absent / malformed headers, throws only on explicit control-character / header-injection-shape input. Operators upstream of this primitive (proxies, framework middleware) already split CRLF; the in-string control-byte check is a defense-in-depth layer.

acceptList() builds the Accept-CH response header so the operator advertises which client-hint headers the page wants.

b.clientHints.parse(headers) #

stable0.8.91

Parse the Sec-CH-UA-* family from an HTTP request's headers object. headers is the Node req.headers shape (header names are already lowercased per Node convention). Returns a normalized { brands, mobile, platform, platformVersion, arch, bitness, model, fullVersionList, wow64, formFactors, raw } shape:

- brands: [ { brand, version, params } ] from Sec-CH-UA - mobile: boolean from Sec-CH-UA-Mobile (?1/?0) — null if absent / malformed - platform: sf-string from Sec-CH-UA-Platform - platformVersion: sf-string from Sec-CH-UA-Platform-Version - arch: sf-string from Sec-CH-UA-Arch - bitness: sf-string from Sec-CH-UA-Bitness - model: sf-string from Sec-CH-UA-Model - fullVersionList: brand-list from Sec-CH-UA-Full-Version-List - wow64: boolean from Sec-CH-UA-WoW64 - formFactors: brand-list from Sec-CH-UA-Form-Factors - raw: { "": "" } for every Sec-CH-* header in the input, so operators can audit the full set without re-walking req.headers.

Returns null when headers is not an object. Individual fields are null when the corresponding header is absent or malformed (defensive request-shape reader). Refuses control characters in any present Sec-CH-* value (header-injection defense).

var ch = b.clientHints.parse(req.headers);
if (ch && ch.mobile === true) renderMobilePage(req, res);
else if (ch && ch.platform === "Windows") renderWindowsPage(req, res);
else renderDefaultPage(req, res);

b.clientHints.acceptList(hintNames) #

stable0.8.91

Build the Accept-CH response header value advertising which client-hint request headers the operator wants the browser to include on subsequent requests. hintNames is an array of canonical Sec-CH-* header names; the primitive refuses unknown hint names (typo defense — accept-ch: Sec-CH-UA-Plateform silently neuters the negotiation).

Operators set Accept-CH on the HTML document response. The browser sends the listed hints on every subsequent same-origin navigation / sub-resource request.

res.setHeader("Accept-CH", b.clientHints.acceptList([
  "Sec-CH-UA-Platform",
  "Sec-CH-UA-Platform-Version",
  "Sec-CH-UA-Mobile",
]));
// → "Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA-Mobile"

b.clientHints.isKnownHint(headerName) #

stable0.8.91

Returns true when headerName matches one of the well-known Sec-CH-* hint headers (case-insensitive). Operators auditing inbound headers walk the request and call this to identify negotiation-related hints without keyword-matching.

b.clientHints.isKnownHint("Sec-CH-UA-Mobile");    // → true
b.clientHints.isKnownHint("sec-ch-ua-platform");  // → true
b.clientHints.isKnownHint("X-Custom");            // → false

Last updated 2026-08-08T16:39:49.652Z by seeder.