import type { LocaleDetector } from "../detector.types.js"; import { acceptLanguageDetector } from "../detectors/accept-language/accept-language.js"; import { cloudflareIpGeoDetector } from "../detectors/cloudflare-ip-geo/cloudflare-ip-geo.js"; import { cookieDetector } from "../detectors/cookie/cookie.js"; import { fallbackDetector } from "../detectors/fallback/fallback.js"; import { htmlLangDetector } from "../detectors/html-lang/html-lang.js"; import { localStorageDetector } from "../detectors/local-storage/local-storage.js"; import { navigatorDetector } from "../detectors/navigator/navigator.js"; import { querystringDetector } from "../detectors/querystring/querystring.js"; import { userPreferenceDetector } from "../detectors/user-preference/user-preference.js"; import type { DefaultDetectorChainOptions } from "./default-chain.types.js"; /** * Build the canonical 9-entry (or 8-entry) detector chain consumed * by `` and `useLocaleDetection`. * * Order (per spec "Default chain order"): * * 1. `querystring` * 2. `userPreference` — only when `opts.userPreferenceEndpoint` is set * 3. `cookie` * 4. `localStorage` * 5. `htmlLang` * 6. `acceptLanguage` * 7. `navigator` * 8. `cloudflareIpGeo` * 9. `fallback` * * The chain is returned as a fresh array on every call so callers * can mutate or filter the result without affecting subsequent * invocations. */ export function defaultDetectorChain( options: DefaultDetectorChainOptions ): LocaleDetector[] { const detectors: LocaleDetector[] = [querystringDetector()]; if ( typeof options.userPreferenceEndpoint === "string" && options.userPreferenceEndpoint !== "" ) { detectors.push( userPreferenceDetector({ endpoint: options.userPreferenceEndpoint, }) ); } detectors.push(cookieDetector()); detectors.push(localStorageDetector()); detectors.push(htmlLangDetector()); detectors.push(acceptLanguageDetector()); detectors.push(navigatorDetector()); detectors.push(cloudflareIpGeoDetector()); detectors.push(fallbackDetector(options.fallback)); return detectors; }