Files
skills/docs/localization/i18n/react-i18n/src/hooks/use-locale-adapter/use-locale-adapter.md
2026-05-29 08:20:56 +01:00

3.4 KiB

useLocaleAdapter

(no submodules)

Purpose

useLocaleAdapter<TLocale>(id) resolves a registered LocaleAdapterPlugin<TLocale> against the active locale and returns its library-specific output. The canonical use case is react-day-picker's <Calendar>, which wants a date-fns Locale object — the component calls useLocaleAdapter<Locale>("date-fns") and the consumer registers an adapter that maps the active BCP-47 locale to the corresponding date-fns reference. The package stays library-agnostic; the consumer wires the date / time library they already use.

Features

  • Strict resolution — throws REACT_I18N.LOCALE_ADAPTER_NOT_REGISTERED for an unknown id.
  • Memoized on (registry, id, locale) so a no-op re-render does not re-invoke plugin.resolve.
  • Built-in "intl" identity adapter is auto-registered by <RegistryProvider> so any consumer that just needs the locale string back gets it without registering a plugin.

Usage: Basic Example

import { useLocaleAdapter } from "@suaveplan/react-i18n";

function HtmlLang(): JSX.Element {
    const lang = useLocaleAdapter<string>("intl");
    return <meta name="content-language" content={lang} />;
}

Usage: Advanced Example

A <Calendar> component asks for the date-fns adapter:

import { useLocaleAdapter } from "@suaveplan/react-i18n";
import { DayPicker } from "react-day-picker";
import type { Locale as DateFnsLocale } from "date-fns";

function Calendar(props: CalendarProps): JSX.Element {
    const dateFnsLocale = useLocaleAdapter<DateFnsLocale>("date-fns");
    return <DayPicker {...props} locale={dateFnsLocale} />;
}

The consumer wires the adapter once in <RegistryProvider>:

import { createDateFnsLocaleAdapter, RegistryProvider } from "@suaveplan/react-i18n";
import { enGB, frFR, zhCN } from "date-fns/locale";

const dateFnsAdapter = createDateFnsLocaleAdapter({
    locales: { enGB, frFR, zhCN },
});

<RegistryProvider plugins={[{ kind: "locale-adapter", plugin: dateFnsAdapter }]}>
    {/* … Calendar resolves "date-fns" to the active locale's Locale object */}
</RegistryProvider>;

Without registering the adapter, <Calendar> throws REACT_I18N.LOCALE_ADAPTER_NOT_REGISTERED on first render. This is intentional — silent fallback to a hardcoded English locale would be surprising in an RTL locale.

API Reference

useLocaleAdapter<TLocale>(id: string): TLocale

  • id: the registered plugin's id. The built-in "intl" is auto-registered; other ids ("date-fns", "luxon", "temporal") are consumer-registered.

Throws ReactI18nError(REACT_I18N.LOCALE_ADAPTER_NOT_REGISTERED) for an unknown id, REACT_I18N.REGISTRY_NOT_PROVIDED outside a <RegistryProvider>.

Implementation Notes

  • The hook is memoized on (registry, id, resolvedLocale). Adapter implementations must be pure — calling resolve(locale) twice with the same locale must return referentially-equal output for the memo to be useful.
  • Adapters typically hold their locale map at construction time (see createDateFnsLocaleAdapter); this means the adapter object identity is stable across renders, which keeps the memoization key stable.
  • A consumer registering multiple adapters under different ids (e.g. "date-fns" AND "luxon") gets two independent resolution paths. Components decide which library they need by passing the matching id.