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.sortwith 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.fallbackLocaleonce 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.