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

3.6 KiB

querystringDetector

(no submodules)

Purpose

querystringDetector is a LocaleDetector that reads the active locale from a URL search parameter. It runs in both browser and server environments, making it the canonical first link in the default detector chain — explicit user intent expressed through ?lang=fr-FR always overrides every other source (cookie, localStorage, geo lookup, …) per the spec scenario "querystring overrides cookie".

The detector is intentionally minimal: it never persists a value (so sharing a ?lang=… link does not pollute the user's stored preference), it does not throw when the param is absent, and it never reaches into window-level globals when a server-side request context is supplied.

Features

  • Configurable parameter name via opts.paramName (default "lang")
  • Server input via ctx.request.url.searchParams
  • Browser input via window.location.search
  • Returns null for missing params, empty values, or environments where neither input source exists
  • environment: "both" — eligible on every chain run

Usage: Basic Example

import { querystringDetector } from "@suaveplan/react-i18n/detector/querystring/querystring";
import { createDetectorChain } from "@suaveplan/i18n/detector";

const chain = createDetectorChain([querystringDetector()]);
const result = await chain.detect({
    request: {
        headers: new Headers(),
        url: new URL("https://example.com/?lang=fr-FR"),
    },
    responseHeaders: new Headers(),
    supportedLocales: ["en-GB", "fr-FR"],
    fallbackLocale: "en-GB",
});
// → { locale: "fr-FR", detector: "querystring", rawValue: "fr-FR" }

Usage: Advanced Example

import { querystringDetector } from "@suaveplan/react-i18n/detector/querystring/querystring";
import { defaultDetectorChain } from "@suaveplan/react-i18n/detector/default-chain/default-chain";

// Replace the default `?lang=` entry with `?locale=` for a host app
// that already uses that parameter, while keeping every other detector.
const chain = defaultDetectorChain({ fallback: "en-GB" }).map((d) =>
    d.name === "querystring" ? querystringDetector({ paramName: "locale" }) : d
);

API Reference

querystringDetector(options?: QuerystringDetectorOptions): LocaleDetector

Param Type Default Description
options QuerystringDetectorOptions? {} Optional { paramName?: string } overrides.

Returns a LocaleDetector with name: "querystring" and environment: "both". The detector exposes only detect(ctx); it does not implement cache(...) (the URL is never written).

QuerystringDetectorOptions

Field Type Default Description
paramName string "lang" Search-parameter name the detector reads

Implementation Notes

  • The detector strictly prefers ctx.request over window.location so SSR contexts that happen to leak a globalThis.location (e.g. test harnesses) do not override the request the application is rendering.
  • An empty string value (e.g. ?lang=) is treated as "no preference" per the chain contract — the detector falls through, never wins.
  • The implementation is allocation-light (one URLSearchParams on the browser path) and synchronous so the chain runner picks it up in the initial sync pass before any async detector is dispatched.