Files
skills/docs/localization/i18n/react-i18n/src/detector/accept-language/accept-language.md
2026-05-29 08:20:56 +01:00

2.9 KiB

acceptLanguageDetector

(no submodules)

Purpose

acceptLanguageDetector is a server-only LocaleDetector that parses the inbound Accept-Language header per RFC 9110 §5.3.5 and returns the highest-priority entry. It is the canonical fallback when nothing else (querystring, user preference, cookie, geo lookup) has produced a match — every browser submits an Accept-Language header so this detector almost always returns something on a real request.

The detector returns the raw highest-q entry; supported-locale negotiation is the chain runner's responsibility (it calls LocaleResolver.negotiate(raw, supported) to perform BCP-47 fallback).

Features

  • Full RFC 9110 q-value parsing (default 1.0, range [0, 1])
  • Stable sort: ties keep insertion order
  • Wildcard * skipped (no useful locale information)
  • Malformed entries silently skipped
  • environment: "server"

Usage: Basic Example

import { acceptLanguageDetector } from "@suaveplan/react-i18n/detector/accept-language/accept-language";
import { createDetectorChain } from "@suaveplan/i18n/detector";

const chain = createDetectorChain([acceptLanguageDetector()]);

Usage: Advanced Example

import { parseAcceptLanguage } from "@suaveplan/react-i18n/detector/accept-language/accept-language";

// Build a custom detector that biases language groups using the
// canonical RFC 9110 parser exposed by this module.
const groups = parseAcceptLanguage("fr-FR;q=0.5, de-DE;q=0.9, en;q=0.8");
// → [{ locale: "de-DE", q: 0.9 }, { locale: "en", q: 0.8 }, ...]

API Reference

acceptLanguageDetector(): LocaleDetector

Returns a LocaleDetector with name: "acceptLanguage" and environment: "server". Only detect(ctx) is implemented.

parseAcceptLanguage(header: string): AcceptLanguageEntry[]

Parses an Accept-Language header into a sorted descending-by-q array of { locale, q } entries. Exposed for tests and as a building block for advanced consumers building custom detectors.

AcceptLanguageEntry

interface AcceptLanguageEntry {
    readonly locale: string;
    readonly q: number;
}

Implementation Notes

  • The parser uses Array.prototype.sort with a tie-breaking insertion-index because the JavaScript spec only guarantees a stable sort in modern engines; the explicit index keeps the behaviour deterministic across older runtimes too.
  • Wildcards are skipped at parse time — they never appear in the returned array. The chain runner still has the option of consulting ctx.fallbackLocale once every detector returns null.
  • An entry whose q-value is unparseable, negative, or > 1 is treated as a malformed entry per RFC 9110 ("the recipient SHOULD discard") rather than coerced to the documented default — this keeps the parser strict at the field level while staying liberal at the header level.