Home/Blog/How do I handle User-Agent Client Hints in modern browsers?
Web Development

How do I handle User-Agent Client Hints in modern browsers?

Master User-Agent Client Hints, understand the privacy benefits and implementation requirements, and prepare for the future of browser identification.

By Inventive HQ Team
How do I handle User-Agent Client Hints in modern browsers?

Understanding the User-Agent Client Hints Revolution

The web standards community has recognized that the traditional User-Agent string is problematic from both privacy and technical perspectives. The User-Agent is sent with every HTTP request, contains detailed information about the user's browser and operating system, and is often unreliable due to browser spoofing for compatibility reasons. To address these issues, a new standard called User-Agent Client Hints (UA-CH) has been developed and is rapidly being adopted by modern browsers.

User-Agent Client Hints represent a fundamental shift in how browsers communicate their capabilities and characteristics to servers. Rather than sending a single, complex, often-unreliable User-Agent string with every request, Client Hints provide a mechanism for servers to explicitly request specific information about the client, which browsers then provide transparently.

This approach offers significant benefits: it gives users more control over what information is shared, it makes server code more predictable and reliable, and it aligns with privacy-first principles that are becoming increasingly important in web development.

The Traditional Problem with User-Agent Strings

Before understanding the solution, it's important to understand the problem. The traditional User-Agent string looks something like:

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

This string contains:

  • Rendering engine information (WebKit)
  • Browser name and version (Chrome 120)
  • Operating system (Windows 10, 64-bit)
  • Other identifiers and vendor information

The problems with this approach:

  1. Privacy: It reveals detailed information about every user's system to every server they visit
  2. Unreliability: Browsers lie about their identity for compatibility (notice Chrome claiming to be Safari)
  3. Inefficiency: All this information is sent with every request, even when the server doesn't need it
  4. Maintenance burden: Parsing these strings is error-prone and requires constant updates as new browser versions are released

User-Agent Client Hints address all these issues by making the process explicit and requesting only what's needed.

How User-Agent Client Hints Work

Client Hints work through HTTP headers. A server can indicate which Client Hints it wants by sending an Accept-CH header:

Accept-CH: sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform

The browser then responds with the requested information in subsequent requests:

sec-ch-ua: "Google Chrome";v="120", "Chromium";v="120", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"

This approach is much more explicit and transparent than the old system.

Available Client Hints

Several Client Hints are available, each providing specific information:

Basic Hints:

  • sec-ch-ua: The browser name and major version (multiple values for privacy)
  • sec-ch-ua-mobile: Whether the device is mobile (true/false)
  • sec-ch-ua-platform: The operating system name

Extended Hints:

  • sec-ch-ua-arch: Processor architecture (x86, arm, etc.)
  • sec-ch-ua-bitness: Whether the processor is 32-bit or 64-bit
  • sec-ch-ua-full-version-list: Full version numbers for all rendering engines and browsers
  • sec-ch-ua-model: The device model (for mobile devices)
  • sec-ch-ua-form-factors: Available form factors (smartphone, tablet, etc.)

Different browsers support different subsets of these hints, and the available hints are evolving as the standard develops.

Server-Side Implementation

Implementing User-Agent Client Hints on the server requires:

  1. Sending Accept-CH header: Declare which hints you want
  2. Parsing the response headers: Extract the information from the returned hints
  3. Graceful fallback: Handle cases where hints aren't available

Here's a JavaScript/Node.js example:

app.use((req, res, next) => {
  // Declare which hints we want
  res.set('Accept-CH', 'sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform');

  // Parse the hints from the request
  const hints = {
    ua: req.get('sec-ch-ua'),
    isMobile: req.get('sec-ch-ua-mobile') === '?1',
    platform: req.get('sec-ch-ua-platform'),
    arch: req.get('sec-ch-ua-arch'),
  };

  // Use the hints for responsive serving
  res.locals.isSmallScreen = hints.isMobile;

  next();
});

PHP example:

header('Accept-CH: sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform');

$hints = [
    'ua' => $_SERVER['HTTP_SEC_CH_UA'] ?? null,
    'isMobile' => ($_SERVER['HTTP_SEC_CH_UA_MOBILE'] ?? '') === '?1',
    'platform' => $_SERVER['HTTP_SEC_CH_UA_PLATFORM'] ?? null,
];

// Use the hints for server-side logic

Client-Side JavaScript Access

Modern browsers also allow JavaScript to access Client Hints through the User-Agent data API:

async function getClientHints() {
  if (!navigator.userAgentData) {
    // Fallback for browsers that don't support User-Agent Client Hints
    return null;
  }

  // Basic information is always available
  const mobile = navigator.userAgentData.mobile;
  const platform = navigator.userAgentData.platform;
  const brands = navigator.userAgentData.brands;

  // Request additional information
  const fullData = await navigator.userAgentData.getHighEntropyValues([
    'architecture',
    'bitness',
    'model',
    'fullVersionList'
  ]);

  return {
    mobile,
    platform,
    brands,
    ...fullData
  };
}

getClientHints().then(hints => {
  if (hints) {
    console.log('Device is mobile:', hints.mobile);
    console.log('Platform:', hints.platform);
  }
});

Note the distinction between "low entropy" values (always available without requesting, like mobile and platform) and "high entropy" values (require explicit request, like architecture and model). This design encourages privacy by making it clear when detailed information is being requested.

Privacy Benefits

User-Agent Client Hints provide several privacy improvements:

  1. User control: Users can configure which hints are sent and to which sites
  2. Explicit requests: Servers must explicitly declare which hints they need
  3. Limited sharing: Not all hints are sent with every request
  4. Fingerprinting resistance: The information provided is standardized, making it harder to fingerprint individual users

Browsers can also implement privacy features like reducing precision in some hints or adding noise to make fingerprinting less reliable.

Handling Missing Hint Support

Not all browsers support User-Agent Client Hints yet. Your code needs to gracefully handle cases where hints aren't available:

function getDeviceType() {
  // Try Client Hints first
  if (navigator.userAgentData && !navigator.userAgentData.mobile) {
    return 'desktop';
  }

  // Fallback: use User-Agent string for older browsers
  if (navigator.userAgent.match(/mobile/i)) {
    return 'mobile';
  }

  // Or use other detection methods
  return detectDeviceType();
}

This ensures your application works in both modern browsers with Client Hints support and older browsers that only have traditional User-Agent strings.

Sending Hints to Third-Party Services

A key consideration is how Client Hints interact with third-party resources. By default, hints are only sent to the same origin where they were requested. If you need to send hints to third-party services (analytics, advertising, etc.), you need to explicitly declare this:

<img src="https://analytics.example.com/pixel"
     crossorigin="anonymous"
     href="https://analytics.example.com">

You can also use the permissions-policy header to control which third-party services receive Client Hints.

Migration Strategy from User-Agent Parsing

If you're currently using User-Agent parsing, here's a migration strategy:

  1. Phase 1: Implement Client Hints alongside existing User-Agent parsing
  2. Phase 2: Update feature detection code to prefer Client Hints
  3. Phase 3: Log which browsers still don't support Client Hints
  4. Phase 4: Gradually deprecate User-Agent parsing as browser support improves
function getBrowserInfo() {
  // Prefer Client Hints
  if (navigator.userAgentData) {
    return {
      isMobile: navigator.userAgentData.mobile,
      platform: navigator.userAgentData.platform,
      source: 'client-hints'
    };
  }

  // Fallback to User-Agent parsing
  return {
    isMobile: navigator.userAgent.match(/mobile/i),
    platform: getPlatformFromUA(navigator.userAgent),
    source: 'user-agent'
  };
}

Browser Support and Timeline

Current support for User-Agent Client Hints:

  • Chromium-based browsers (Chrome, Edge, Opera): Full support
  • Firefox: Partial support, expanding
  • Safari: Minimal support, gradual rollout
  • Other browsers: Variable support

The timeline for deprecating the User-Agent string is still being determined, but it's clear that the long-term direction is toward Client Hints.

Common Use Cases

Responsive Design Decision Making: Use sec-ch-ua-mobile to determine whether to serve mobile or desktop layouts

Device-Specific Optimization: Use architecture and bitness hints to optimize binary downloads

Analytics: Replace User-Agent parsing with Client Hints for more reliable device detection

Security Decisions: Use hints to inform security policies (for example, requiring stronger authentication on mobile devices)

Best Practices

  1. Be explicit about what you need: Only request hints you actually use
  2. Respect user privacy: Avoid requesting high-entropy hints unless necessary
  3. Provide fallbacks: Always handle cases where hints aren't available
  4. Validate hint values: Client Hints can be spoofed; don't make critical security decisions based solely on them
  5. Monitor browser support: Track which hints different browsers support and plan accordingly

Conclusion

User-Agent Client Hints represent the future of how browsers communicate their capabilities to servers. By providing explicit, transparent, and privacy-conscious information sharing, they address the fundamental problems with the traditional User-Agent string. While browser support is still evolving, implementing support for Client Hints now—while maintaining fallbacks to User-Agent parsing—ensures your application works across current and future browsers. As the web community moves away from User-Agent string parsing, understanding and implementing Client Hints is becoming essential for modern web development.

Need Expert IT & Security Guidance?

Our team is ready to help protect and optimize your business technology infrastructure.