first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,656 @@
# @suaveplan/react-i18n - React bindings for @suaveplan/i18n: TranslationProvider, hooks, <Trans>, <LanguageSwitcher>, locale-detection chain glue, branded TranslationKey contract.
## Summary
React bindings for `@suaveplan/i18n`. Ships the `<TranslationProvider>`,
twelve hooks, four headless components, the class-component HOC, the
nine built-in locale detectors plus the default chain, the
`useLocaleDetection` hook, the branded `TranslationKey` typing contract,
the `tDynamic` runtime escape hatch, the React-tier OTel instruments,
and the warn-once / identity-translator soft-failure substrate. The
package is the leaf-most React library in the project — every other
React package augments it (via `ContributedTranslationKeys`) but no
React package may declare it as a downstream dependency. The
[`check-no-backwards-deps.ts`](../../../scripts/lint/check-no-backwards-deps.ts)
CI gate enforces that invariant on every commit.
<!-- begin:auto-docs -->
## Documentation tree
- [i18n-suspense](./src/components/i18n-suspense/i18n-suspense.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [fallback-bundle](./src/components/i18n-suspense/fallback-bundle.md) — Ships the strings that `<I18nSuspense>` needs before the active catalog loads its own copies. Consumers can override th…
- [i18n-suspense](./src/components/i18n-suspense/i18n-suspense.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [stringify-children](./src/components/trans/stringify-children.md) — Helpers that translate a `<Trans>` `children` block into a canonical ICU message body string so the message parser rend…
- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [create-i18n-config](./src/config/create-i18n-config.md) — Builds a validated `I18nConfig` from a caller-supplied option bag and is the canonical entry point for `<TranslationPro…
- [to-i18n-instance-options](./src/config/to-i18n-instance-options.md) — Translates a Zod-parsed `I18nConfig` (the React-tier shape) into the universal-core `I18nInstanceOptions` accepted by `…
- [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [error-codes](./src/errors/error-codes.md) — Registers the five stable error codes used by `@suaveplan/react-i18n` under the `REACT_I18N` namespace via `defineCodes…
- [react-i18n-error](./src/errors/react-i18n-error.md) — Defines `ReactI18nError`, the single error class thrown by the React surface of `@suaveplan/react-i18n`. It extends the…
- [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [detector-chain-context](./src/hooks/use-locale-detection/detector-chain-context.md) — `DetectorChainContext` is the React context that carries the configured locale-detector chain (plus any SSR-authoritati…
- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [observability](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [react-i18n-metrics](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [provider-context](./src/provider/provider-context.md) — Defines the React context that carries the active `I18nInstance` from `@suaveplan/i18n` to every descendant of `<Transl…
- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- built-in — <!-- begin:auto-docs --> _(no submodules)…
- [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [registry-context](./src/registry/registry-context.md) — Module-scoped React context that carries the active `ReactI18nRegistry` to descendants of `<RegistryProvider>`. Direct…
- [registry-provider](./src/registry/registry-provider.md) — `<RegistryProvider>` is the React-context surface for `ReactI18nRegistry`. It mounts a fresh registry per tree, registe…
- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- built-in — <!-- begin:auto-docs --> _(no submodules)…
- [registry.schemas](./src/registry/registry.schemas.md) — Strict-object Zod schemas for every plugin kind accepted by `ReactI18nRegistry`. The schemas are the boundary at which…
- [use-registry](./src/registry/use-registry.md) — These hooks read the active `ReactI18nRegistry` from React context. The strict variant `useReactI18nRegistry()` throws…
- [schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [i18n-config.schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [t-dynamic](./src/translation-key/t-dynamic.md) — `tDynamic(i18n, key, values?)` is the rare-use escape hatch for translation lookups whose key cannot be statically know…
- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [env](./src/utils/env.md) — Provides the single environment-detection helper the React surface uses to switch between dev-mode loud-failure and pro…
- [identity-instance](./src/utils/identity-instance.md) — Provides the identity translator used as the production-mode fallback when a `useTranslation()` (or any sibling hook) i…
- [warn-once-per-process](./src/utils/warn-once-per-process.md) — Implements the warn-once-per-process dedup ring used by every production-mode soft-failure path in `@suaveplan/react-i1…
<!-- end:auto-docs --> - [fallback-bundle](./src/components/i18n-suspense/fallback-bundle.md) — Ships the strings that `<I18nSuspense>` needs before the active catalog loads its own copies. Consumers can override th…
- [i18n-suspense](./src/components/i18n-suspense/i18n-suspense.md) — <!-- begin:auto-docs --> _(no submodules)_- [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_- [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_- [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_- [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_- [stringify-children](./src/components/trans/stringify-children.md) — Helpers that translate a `<Trans>` `children` block into a canonical ICU message body string so the message parser rend…
- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-i18n-config](./src/config/create-i18n-config.md) — Builds a validated `I18nConfig` from a caller-supplied option bag and is the canonical entry point for `<TranslationPro…
- [to-i18n-instance-options](./src/config/to-i18n-instance-options.md) — Translates a Zod-parsed `I18nConfig` (the React-tier shape) into the universal-core `I18nInstanceOptions` accepted by `…
- [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_- [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_- [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_- [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_- [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_- [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_- [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_- [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_- [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_- [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_- [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_- [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_- [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_- [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_- [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_- [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_- [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_- [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-codes](./src/errors/error-codes.md) — Registers the five stable error codes used by `@suaveplan/react-i18n` under the `REACT_I18N` namespace via `defineCodes…
- [react-i18n-error](./src/errors/react-i18n-error.md) — Defines `ReactI18nError`, the single error class thrown by the React surface of `@suaveplan/react-i18n`. It extends the…
- [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_- [detector-chain-context](./src/hooks/use-locale-detection/detector-chain-context.md) — `DetectorChainContext` is the React context that carries the configured locale-detector chain (plus any SSR-authoritati…
- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [react-i18n-metrics](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_- [provider-context](./src/provider/provider-context.md) — Defines the React context that carries the active `I18nInstance` from `@suaveplan/i18n` to every descendant of `<Transl…
- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_- [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_- [registry-context](./src/registry/registry-context.md) — Module-scoped React context that carries the active `ReactI18nRegistry` to descendants of `<RegistryProvider>`. Direct…
- [registry-provider](./src/registry/registry-provider.md) — `<RegistryProvider>` is the React-context surface for `ReactI18nRegistry`. It mounts a fresh registry per tree, registe…
- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_- [registry.schemas](./src/registry/registry.schemas.md) — Strict-object Zod schemas for every plugin kind accepted by `ReactI18nRegistry`. The schemas are the boundary at which…
- [use-registry](./src/registry/use-registry.md) — These hooks read the active `ReactI18nRegistry` from React context. The strict variant `useReactI18nRegistry()` throws…
- [schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [i18n-config.schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_- [t-dynamic](./src/translation-key/t-dynamic.md) — `tDynamic(i18n, key, values?)` is the rare-use escape hatch for translation lookups whose key cannot be statically know…
- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_- [env](./src/utils/env.md) — Provides the single environment-detection helper the React surface uses to switch between dev-mode loud-failure and pro…
- [identity-instance](./src/utils/identity-instance.md) — Provides the identity translator used as the production-mode fallback when a `useTranslation()` (or any sibling hook) i…
- [warn-once-per-process](./src/utils/warn-once-per-process.md) — Implements the warn-once-per-process dedup ring used by every production-mode soft-failure path in `@suaveplan/react-i1…
- [fallback-bundle](./src/components/i18n-suspense/fallback-bundle.md) — Ships the strings that `<I18nSuspense>` needs before the active catalog loads its own copies. Consumers can override th…
- [i18n-suspense](./src/components/i18n-suspense/i18n-suspense.md) — <!-- begin:auto-docs --> _(no submodules)_- [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_- [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_- [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_- [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_- [stringify-children](./src/components/trans/stringify-children.md) — Helpers that translate a `<Trans>` `children` block into a canonical ICU message body string so the message parser rend…
- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-i18n-config](./src/config/create-i18n-config.md) — Builds a validated `I18nConfig` from a caller-supplied option bag and is the canonical entry point for `<TranslationPro…
- [to-i18n-instance-options](./src/config/to-i18n-instance-options.md) — Translates a Zod-parsed `I18nConfig` (the React-tier shape) into the universal-core `I18nInstanceOptions` accepted by `…
- [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_- [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_- [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_- [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_- [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_- [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_- [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_- [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_- [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_- [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_- [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_- [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_- [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_- [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_- [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_- [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_- [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_- [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-codes](./src/errors/error-codes.md) — Registers the five stable error codes used by `@suaveplan/react-i18n` under the `REACT_I18N` namespace via `defineCodes…
- [react-i18n-error](./src/errors/react-i18n-error.md) — Defines `ReactI18nError`, the single error class thrown by the React surface of `@suaveplan/react-i18n`. It extends the…
- [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_- [detector-chain-context](./src/hooks/use-locale-detection/detector-chain-context.md) — `DetectorChainContext` is the React context that carries the configured locale-detector chain (plus any SSR-authoritati…
- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [react-i18n-metrics](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_- [provider-context](./src/provider/provider-context.md) — Defines the React context that carries the active `I18nInstance` from `@suaveplan/i18n` to every descendant of `<Transl…
- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_- built-in — <!-- begin:auto-d…
- [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_- [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_- [registry-context](./src/registry/registry-context.md) — Module-scoped React context that carries the active `ReactI18nRegistry` to descendants of `<RegistryProvider>`. Direct…
- [registry-provider](./src/registry/registry-provider.md) — `<RegistryProvider>` is the React-context surface for `ReactI18nRegistry`. It mounts a fresh registry per tree, registe…
- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_- built-in — <!-- begin:auto-d…
- [registry.schemas](./src/registry/registry.schemas.md) — Strict-object Zod schemas for every plugin kind accepted by `ReactI18nRegistry`. The schemas are the boundary at which…
- [use-registry](./src/registry/use-registry.md) — These hooks read the active `ReactI18nRegistry` from React context. The strict variant `useReactI18nRegistry()` throws…
- [schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [i18n-config.schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_- [t-dynamic](./src/translation-key/t-dynamic.md) — `tDynamic(i18n, key, values?)` is the rare-use escape hatch for translation lookups whose key cannot be statically know…
- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_- [env](./src/utils/env.md) — Provides the single environment-detection helper the React surface uses to switch between dev-mode loud-failure and pro…
- [identity-instance](./src/utils/identity-instance.md) — Provides the identity translator used as the production-mode fallback when a `useTranslation()` (or any sibling hook) i…
- [warn-once-per-process](./src/utils/warn-once-per-process.md) — Implements the warn-once-per-process dedup ring used by every production-mode soft-failure path in `@suaveplan/react-i1…
- [fallback-bundle](./src/components/i18n-suspense/fallback-bundle.md) — Ships the strings that `<I18nSuspense>` needs before the active catalog loads its own copies. Consumers can override th…
- [i18n-suspense](./src/components/i18n-suspense/i18n-suspense.md) — <!-- begin:auto-docs --> _(no submodules)_- [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_- [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_- [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_- [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_- [stringify-children](./src/components/trans/stringify-children.md) — Helpers that translate a `<Trans>` `children` block into a canonical ICU message body string so the message parser rend…
- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-i18n-config](./src/config/create-i18n-config.md) — Builds a validated `I18nConfig` from a caller-supplied option bag and is the canonical entry point for `<TranslationPro…
- [to-i18n-instance-options](./src/config/to-i18n-instance-options.md) — Translates a Zod-parsed `I18nConfig` (the React-tier shape) into the universal-core `I18nInstanceOptions` accepted by `…
- [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_- [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_- [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_- [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_- [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_- [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_- [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_- [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_- [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_- [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_- [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_- [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_- [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_- [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_- [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_- [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_- [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_- [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-codes](./src/errors/error-codes.md) — Registers the five stable error codes used by `@suaveplan/react-i18n` under the `REACT_I18N` namespace via `defineCodes…
- [react-i18n-error](./src/errors/react-i18n-error.md) — Defines `ReactI18nError`, the single error class thrown by the React surface of `@suaveplan/react-i18n`. It extends the…
- [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_- [detector-chain-context](./src/hooks/use-locale-detection/detector-chain-context.md) — `DetectorChainContext` is the React context that carries the configured locale-detector chain (plus any SSR-authoritati…
- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [react-i18n-metrics](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_- [provider-context](./src/provider/provider-context.md) — Defines the React context that carries the active `I18nInstance` from `@suaveplan/i18n` to every descendant of `<Transl…
- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_- built-in — <!-- begin:auto-docs --> _(no submodules…
- [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_- [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_- [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_- [registry-context](./src/registry/registry-context.md) — Module-scoped React context that carries the active `ReactI18nRegistry` to descendants of `<RegistryProvider>`. Direct…
- [registry-provider](./src/registry/registry-provider.md) — `<RegistryProvider>` is the React-context surface for `ReactI18nRegistry`. It mounts a fresh registry per tree, registe…
- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_- built-in — <!-- begin:auto-docs --> _(no submodules…
- [registry.schemas](./src/registry/registry.schemas.md) — Strict-object Zod schemas for every plugin kind accepted by `ReactI18nRegistry`. The schemas are the boundary at which…
- [use-registry](./src/registry/use-registry.md) — These hooks read the active `ReactI18nRegistry` from React context. The strict variant `useReactI18nRegistry()` throws…
- [schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [i18n-config.schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_- [t-dynamic](./src/translation-key/t-dynamic.md) — `tDynamic(i18n, key, values?)` is the rare-use escape hatch for translation lookups whose key cannot be statically know…
- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_- [env](./src/utils/env.md) — Provides the single environment-detection helper the React surface uses to switch between dev-mode loud-failure and pro…
- [identity-instance](./src/utils/identity-instance.md) — Provides the identity translator used as the production-mode fallback when a `useTranslation()` (or any sibling hook) i…
- [warn-once-per-process](./src/utils/warn-once-per-process.md) — Implements the warn-once-per-process dedup ring used by every production-mode soft-failure path in `@suaveplan/react-i1…
- [fallback-bundle](./src/components/i18n-suspense/fallback-bundle.md) — Ships the strings that `<I18nSuspense>` needs before the active catalog loads its own copies. Consumers can override th…
- [i18n-suspense](./src/components/i18n-suspense/i18n-suspense.md) — <!-- begin:auto-docs --> _(no submodules)_- [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_ - [language-switcher](./src/components/language-switcher/language-switcher.md) — <!-- begin:auto-docs --> _(no submodules)_- [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_ - [missing-key-overlay](./src/components/missing-key-overlay/missing-key-overlay.md) — <!-- begin:auto-docs --> _(no submodules)_- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_ - [stringify-children](./src/components/trans/stringify-children.md) — Helpers that translate a `<Trans>` `children` block into a canonical ICU message body string so the message parser rend…
- [trans](./src/components/trans/trans.md) — <!-- begin:auto-docs --> _(no submodules)_- [create-i18n-config](./src/config/create-i18n-config.md) — Builds a validated `I18nConfig` from a caller-supplied option bag and is the canonical entry point for `<TranslationPro…
- [to-i18n-instance-options](./src/config/to-i18n-instance-options.md) — Translates a Zod-parsed `I18nConfig` (the React-tier shape) into the universal-core `I18nInstanceOptions` accepted by `…
- [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_ - [accept-language](./src/detector/accept-language/accept-language.md) — <!-- begin:auto-docs --> _(no submodules)_- [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_ - [cloudflare-ip-geo](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md) — <!-- begin:auto-docs --> _(no submodules)_- [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_ - [cookie](./src/detector/cookie/cookie.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_ - [default-chain](./src/detector/default-chain/default-chain.md) — <!-- begin:auto-docs --> _(no submodules)_- [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_ - [fallback](./src/detector/fallback/fallback.md) — <!-- begin:auto-docs --> _(no submodules)_- [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_ - [html-lang](./src/detector/html-lang/html-lang.md) — <!-- begin:auto-docs --> _(no submodules)_- [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_ - [local-storage](./src/detector/local-storage/local-storage.md) — <!-- begin:auto-docs --> _(no submodules)_- [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_ - [navigator](./src/detector/navigator/navigator.md) — <!-- begin:auto-docs --> _(no submodules)_- [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_ - [querystring](./src/detector/querystring/querystring.md) — <!-- begin:auto-docs --> _(no submodules)_- [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_ - [user-preference](./src/detector/user-preference/user-preference.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-codes](./src/errors/error-codes.md) — Registers the five stable error codes used by `@suaveplan/react-i18n` under the `REACT_I18N` namespace via `defineCodes…
- [react-i18n-error](./src/errors/react-i18n-error.md) — Defines `ReactI18nError`, the single error class thrown by the React surface of `@suaveplan/react-i18n`. It extends the…
- [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_ - [with-translation](./src/hoc/with-translation/with-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-currency](./src/hooks/use-currency/use-currency.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-date](./src/hooks/use-date/use-date.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-direction](./src/hooks/use-direction/use-direction.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-error-message](./src/hooks/use-error-message/use-error-message.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-formatter](./src/hooks/use-formatter/use-formatter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-i18n](./src/hooks/use-i18n/use-i18n.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-list](./src/hooks/use-list/use-list.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-locale](./src/hooks/use-locale/use-locale.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-locale-adapter](./src/hooks/use-locale-adapter/use-locale-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_ - [detector-chain-context](./src/hooks/use-locale-detection/detector-chain-context.md) — `DetectorChainContext` is the React context that carries the configured locale-detector chain (plus any SSR-authoritati…
- [use-locale-detection](./src/hooks/use-locale-detection/use-locale-detection.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-number](./src/hooks/use-number/use-number.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-plural](./src/hooks/use-plural/use-plural.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-relative-time](./src/hooks/use-relative-time/use-relative-time.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-translate](./src/hooks/use-translate/use-translate.md) — <!-- begin:auto-docs --> _(no submodules)_- [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_ - [use-translation](./src/hooks/use-translation/use-translation.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_ - [react-i18n-metrics](./src/observability/react-i18n-metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_ - [provider-context](./src/provider/provider-context.md) — Defines the React context that carries the active `I18nInstance` from `@suaveplan/i18n` to every descendant of `<Transl…
- [provider](./src/provider/provider.md) — <!-- begin:auto-docs --> _(no submodules)_- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_ - [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_ - [built-in](./src/registry/formatters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_ - [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_ - [built-in](./src/registry/locale-adapters/built-in/built-in.md) — <!-- begin:auto-docs --> _(no submodules)_ - [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_ - [post-processors](./src/registry/post-processors/post-processors.md) — <!-- begin:auto-docs --> _(no submodules)_ - [registry-context](./src/registry/registry-context.md) — Module-scoped React context that carries the active `ReactI18nRegistry` to descendants of `<RegistryProvider>`. Direct…
- [registry-provider](./src/registry/registry-provider.md) — `<RegistryProvider>` is the React-context surface for `ReactI18nRegistry`. It mounts a fresh registry per tree, registe…
- [registry](./src/registry/registry.md) — <!-- begin:auto-docs --> _(no submodules)_ - [registry.schemas](./src/registry/registry.schemas.md) — Strict-object Zod schemas for every plugin kind accepted by `ReactI18nRegistry`. The schemas are the boundary at which…
- [use-registry](./src/registry/use-registry.md) — These hooks read the active `ReactI18nRegistry` from React context. The strict variant `useReactI18nRegistry()` throws…
- [schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_ - [i18n-config.schemas](./src/schemas/i18n-config.schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_ - [t-dynamic](./src/translation-key/t-dynamic.md) — `tDynamic(i18n, key, values?)` is the rare-use escape hatch for translation lookups whose key cannot be statically know…
- [translation-key](./src/translation-key/translation-key.md) — <!-- begin:auto-docs --> _(no submodules)_- [env](./src/utils/env.md) — Provides the single environment-detection helper the React surface uses to switch between dev-mode loud-failure and pro…
- [identity-instance](./src/utils/identity-instance.md) — Provides the identity translator used as the production-mode fallback when a `useTranslation()` (or any sibling hook) i…
- [warn-once-per-process](./src/utils/warn-once-per-process.md) — Implements the warn-once-per-process dedup ring used by every production-mode soft-failure path in `@suaveplan/react-i1…
## Install
```bash
bun add @suaveplan/react-i18n
```
Peer-installs:
```bash
bun add react react-dom
```
The package targets `react ^18.0.0 || ^19.0.0` so `useSyncExternalStore`
is available without the `use-sync-external-store/shim` polyfill. All
internal `@suaveplan/*` deps resolve through the workspace.
## Quick start
The minimum tree wires a Provider, a Trans component, and a hook-driven
locale switch. The `t` function exposed by `useTranslation()` is the
ergonomic-options-bag form from `@suaveplan/i18n`.
```tsx
import {
Trans,
TranslationProvider,
createI18nConfig,
useTranslation,
} from "@suaveplan/react-i18n";
const config = createI18nConfig({
defaultLocale: "en-GB",
fallbackLocale: "en-GB",
supportedLocales: ["en-GB", "fr-FR"],
initialMessages: {
"en-GB": { greeting: "Hello, <bold>{name}</bold>" },
"fr-FR": { greeting: "Bonjour, <bold>{name}</bold>" },
},
});
function Welcome({ name }: { name: string }): JSX.Element {
const { t } = useTranslation();
return (
<>
<p>{t("welcome", { defaultValue: "Welcome" })}</p>
<p>
<Trans
i18nKey="greeting"
values={{ name }}
components={{ bold: <strong /> }}
/>
</p>
</>
);
}
export function App({ children }: { children: React.ReactNode }) {
return (
<TranslationProvider config={config}>
<Welcome name="Alice" />
{children}
</TranslationProvider>
);
}
```
## Modules
Every implementation file ships a sibling `.md` with the canonical
sections (Purpose, Features, Basic + Advanced examples, API Reference,
Implementation Notes). Read them inline alongside the source.
### Provider and context
- [`<TranslationProvider>`](./src/provider/provider.md) — mounts an
`I18nInstance` and exposes it through React context. Accepts either
a caller-managed `i18n` prop (borrowed; not disposed) or a
Provider-managed `config` prop (created on mount, disposed on
unmount).
- [`TranslationContext`](./src/provider/provider-context.md) — the raw
context object for advanced consumers (mostly tests).
### Hooks
- [`useI18n`](./src/hooks/use-i18n/use-i18n.md) — returns the active
`I18nInstance` (or `null` when outside a Provider).
- [`useTranslation`](./src/hooks/use-translation/use-translation.md) —
Suspense-aware `{ t, i18n, ready }` triple. Auto-triggers
`i18n.catalog.preload(locale, namespace)` when a backend is registered
and the namespace is not yet loaded.
- [`useTranslate`](./src/hooks/use-translate/use-translate.md) — terse
alias returning the bound `t` function directly.
- [`useLocale`](./src/hooks/use-locale/use-locale.md) —
`{ locale, setLocale }` re-rendering on `languageChanged`.
- [`useDirection`](./src/hooks/use-direction/use-direction.md) —
`{ direction, locale }` derived from `getTextDirection(locale)`.
- [`useErrorMessage`](./src/hooks/use-error-message/use-error-message.md)
— maps a `SuaveplanError | unknown` to a translated string.
- [`usePlural`](./src/hooks/use-plural/use-plural.md) — the plural
category + rule for a count + locale.
- [`useDate`](./src/hooks/use-date/use-date.md) — memoised
`Intl.DateTimeFormat` wrapper.
- [`useNumber`](./src/hooks/use-number/use-number.md) — memoised
`Intl.NumberFormat` wrapper with the `clearUseNumberCache()` test
helper.
- [`useCurrency`](./src/hooks/use-currency/use-currency.md) — memoised
currency formatter.
- [`useRelativeTime`](./src/hooks/use-relative-time/use-relative-time.md)
— memoised `Intl.RelativeTimeFormat` wrapper.
- [`useList`](./src/hooks/use-list/use-list.md) — memoised
`Intl.ListFormat` wrapper.
- [`useLocaleDetection`](./src/hooks/use-locale-detection/use-locale-detection.md)
— runs the configured detector chain on mount, exposes
`{ detected, source, isPending, redetect }`.
- [`DetectorChainContext` / `DetectorChainProvider`](./src/hooks/use-locale-detection/detector-chain-context.md)
— the context wiring that exposes the chain to descendants.
### Components
- [`<Trans>`](./src/components/trans/trans.md) — rich-text component
using `MessageParser.formatChunks<ReactNode>`. Supports tag
interpolation, nested tags, plural via `count`, and a children-as-
default-message fallback.
- [`<LanguageSwitcher>`](./src/components/language-switcher/language-switcher.md)
— headless render-prop component. Receives
`{ locales, current, change, isPending }`. Wraps `change` in
`useTransition` so namespace loads on locale change do not block
urgent updates.
- [`<MissingKeyOverlay>`](./src/components/missing-key-overlay/missing-key-overlay.md)
— dev-mode overlay listing untranslated keys in real-time, capped at
50 entries with `aria-live="polite"`. Renders `null` in production.
- [`<I18nSuspense>`](./src/components/i18n-suspense/i18n-suspense.md) —
convenience wrapper around React's `<Suspense>` with a default
`aria-live="polite"` fallback and a fallback-render counter
([`react_i18n.suspense.fallback.total`](./src/observability/react-i18n-metrics.md)).
The default loading label is resolved from the active catalog with
the bundled English fallback supplied by
[`fallback-bundle`](./src/components/i18n-suspense/fallback-bundle.md).
- [`stringifyChild` / `childrenToMessageString`](./src/components/trans/stringify-children.md)
— internal `<Trans>` helpers exposed for advanced consumers building
custom rich-text components.
### HOC
- [`withTranslation`](./src/hoc/with-translation/with-translation.md) —
class-component escape hatch. Injects `t` and `i18n` props.
### Locale detectors
Each detector is independently importable from
`@suaveplan/react-i18n` (and tree-shaken when unused).
- [`querystringDetector`](./src/detector/querystring/querystring.md) —
`?lang=...` (server URL or browser `location.search`).
- [`userPreferenceDetector`](./src/detector/user-preference/user-preference.md)
— async fetch against a configurable endpoint; persists on `cache()`.
- [`cookieDetector`](./src/detector/cookie/cookie.md) —
read + write a configurable cookie.
- [`localStorageDetector`](./src/detector/local-storage/local-storage.md)
— browser-only; persists to a configurable key.
- [`htmlLangDetector`](./src/detector/html-lang/html-lang.md) —
reads `document.documentElement.lang`.
- [`acceptLanguageDetector`](./src/detector/accept-language/accept-language.md)
— server-only; parses `Accept-Language` per RFC 9110.
- [`navigatorDetector`](./src/detector/navigator/navigator.md) —
iterates `navigator.languages`.
- [`cloudflareIpGeoDetector`](./src/detector/cloudflare-ip-geo/cloudflare-ip-geo.md)
— server-only; reads `cf-ipcountry` and maps via
`@suaveplan/locale-data`.
- [`fallbackDetector`](./src/detector/fallback/fallback.md) — always
returns the configured fallback. Must appear last in any chain.
- [`defaultDetectorChain`](./src/detector/default-chain/default-chain.md)
— assembles the canonical 9-entry (or 8-entry, when no
`userPreferenceEndpoint` is supplied) chain in spec order.
### Branded TranslationKey
- [`TranslationKey` / `AppTranslationKeys` / `ContributedTranslationKeys`](./src/translation-key/translation-key.md)
— branded string union pattern. Both interfaces start empty;
downstream packages augment `ContributedTranslationKeys` and consumer
apps augment `AppTranslationKeys`.
- [`tDynamic`](./src/translation-key/t-dynamic.md) — runtime escape
hatch. Throws `ReactI18nError(REACT_I18N.UNKNOWN_KEY)` on a missing
key; emits a `warn` log on every call so observability surfaces every
use site.
### Errors and observability
- [`ReactI18nError`](./src/errors/react-i18n-error.md) — `extends
SuaveplanError<ReactI18nCode>`. The only error type the React surface
throws.
- [`REACT_I18N_CODES`](./src/errors/error-codes.md) — five frozen
codes: `NO_PROVIDER`, `NAMESPACE_LOAD_FAILED`, `HYDRATION_MISMATCH`,
`TRANS_INVALID_CHILD`, `UNKNOWN_KEY`.
- [`react_i18n.*` OTel instruments](./src/observability/react-i18n-metrics.md)
— counters (`missing_key.total`, `suspense.fallback.total`),
histogram (`render.duration_ms`), in-memory metrics state ring for
tests, plus the public `getReactI18nMetrics()` /
`recordMissingKey()` / `recordSuspenseFallback()` /
`recordRenderDuration()` helpers.
### Schemas, config, and utils
- [`createI18nConfig`](./src/config/create-i18n-config.md) — Zod
validator that returns a typed `I18nConfig`. Routes
`initialMessages` failures to `ReactI18nError(HYDRATION_MISMATCH)`
and other shape failures to `I18nError(I18N.INVALID_OPTIONS)` so
observability dashboards group on the React-tier code where
appropriate.
- [`toI18nInstanceOptions`](./src/config/to-i18n-instance-options.md) —
pure mapping from `I18nConfig` to the universal-core
`I18nInstanceOptions` shape.
- [`I18nConfigSchema` / `TranslationProviderPropsSchema`](./src/schemas/i18n-config.schemas.md)
— Zod boundary schemas for the Provider's accepted prop shape and the
config bag.
- [`isProductionEnv`](./src/utils/env.md) — single source of truth for
the dev-vs-prod branch every soft-failure path uses.
- [`getIdentityTranslator` / `IDENTITY_TRANSLATION_RETURN`](./src/utils/identity-instance.md)
— no-op identity translator returned by `useTranslation` outside a
Provider in production builds.
- [`warnOncePerProcess`](./src/utils/warn-once-per-process.md) — global
bag-of-warnings dedup so a misbehaving consumer logs each diagnostic
exactly once across the process lifetime.
## Detector chain wiring
The detector chain is the same on the server and the browser; the SSR
render captures the resolved locale, embeds it in `initialLocale`, and
the client hydrates without re-running browser-only detectors (per the
spec's "browser detectors skipped during hydration" requirement).
```tsx
import {
DetectorChainProvider,
TranslationProvider,
cookieDetector,
defaultDetectorChain,
useLocaleDetection,
} from "@suaveplan/react-i18n";
const detectors = defaultDetectorChain({
fallback: "en-GB",
userPreferenceEndpoint: "/api/me/locale",
});
function Bootstrap({ children }: { children: React.ReactNode }) {
return (
<TranslationProvider config={config}>
<DetectorChainProvider detectors={detectors}>
{children}
</DetectorChainProvider>
</TranslationProvider>
);
}
function LocaleStatus(): JSX.Element {
const { detected, source, isPending, redetect } = useLocaleDetection();
return (
<output aria-busy={isPending}>
<span data-testid="locale">{detected ?? "(unresolved)"}</span>
<span data-testid="source">via {source ?? "(none)"}</span>
<button type="button" onClick={() => void redetect()}>
Re-detect
</button>
</output>
);
}
```
For ad-hoc chains, import detectors individually:
```tsx
import {
DetectorChainProvider,
cookieDetector,
fallbackDetector,
navigatorDetector,
} from "@suaveplan/react-i18n";
const detectors = [
cookieDetector({ name: "lang", maxAgeSeconds: 31_536_000 }),
navigatorDetector(),
fallbackDetector("en-GB"),
];
```
## Branded `TranslationKey`
The branded type prevents misspelled translation keys from passing
typecheck. Both the consumer-app interface (`AppTranslationKeys`) and
the downstream-package interface (`ContributedTranslationKeys`) start
empty; augmentation contributes the keys.
### Consumer app augmentation
In your app, generate the augmentation file from the canonical
`locales/en-GB.json` via the
[`generate-translation-types.ts`](./scripts/generate-translation-types.ts)
script:
```bash
bun packages/react/react-i18n/scripts/generate-translation-types.ts \
--source locales/en-GB.json \
--target src/generated/translation-keys.d.ts \
--interface AppTranslationKeys \
--module @suaveplan/react-i18n
```
The script emits a `.d.ts` like:
```ts
declare module "@suaveplan/react-i18n" {
interface AppTranslationKeys {
"app.welcome": true;
"app.signin.title": true;
"app.signin.submit": true;
}
}
```
After importing the generated file once at the app entrypoint, every
typed `t(literalKey)` call typechecks the key against the registered
union.
```ts
import type { TranslationKey } from "@suaveplan/react-i18n";
const k: TranslationKey = "app.welcome"; // ✅ typechecks
const bad: TranslationKey = "appp.welcome"; // ✗ TS error: not assignable
```
### Downstream package augmentation
When publishing a `react-ui-pack-*` or `react-ui-theme-*` package,
augment `ContributedTranslationKeys` instead — that interface is
namespaced for downstream contributions so consumer-app augmentations
do not collide with library-defined keys.
```ts
declare module "@suaveplan/react-i18n" {
interface ContributedTranslationKeys {
"react-ui.dialog.close": true;
"react-ui.dialog.confirm": true;
}
}
```
The downstream package side-effect-imports the augmentation file from
its `index.ts`. Once a consumer adds the package to their tree, the
keys become assignable to `TranslationKey` without any per-consumer
configuration.
## `tDynamic` runtime escape hatch
For the rare case where a key is computed at runtime — most often
mapping an error code like `error.code` to `errors:<code>` — use
`tDynamic`. It performs a runtime catalog lookup and throws
`ReactI18nError(REACT_I18N.UNKNOWN_KEY)` when the key is missing.
Every call also emits a `warn`-level log so observability surfaces
each use site (the typed `t(literalKey)` path is preferred 99% of
the time).
```ts
import { ReactI18nError, tDynamic, useI18n } from "@suaveplan/react-i18n";
function ErrorMessage({ error }: { error: { code: string } }): string {
const i18n = useI18n();
if (i18n === null) return "";
try {
return tDynamic(i18n, `errors:${error.code}`);
} catch (cause) {
if (
cause instanceof ReactI18nError &&
cause.code === "REACT_I18N.UNKNOWN_KEY"
) {
return error.code;
}
throw cause;
}
}
```
## No-backwards-deps gate
`@suaveplan/react-i18n` is the leaf-most React package .
Every downstream React package — `@suaveplan/react-ui`,
`@suaveplan/react-forms`, every `@suaveplan/react-ui-theme-*`, every
`@suaveplan/react-ui-pack-*` — augments
`ContributedTranslationKeys` via TypeScript module augmentation. For
that pattern to stay sound, react-i18n MUST NOT depend on any of those
packages in any of its dep buckets (`dependencies`,
`peerDependencies`, `devDependencies`).
The CI gate at
[`scripts/lint/check-no-backwards-deps.ts`](../../../scripts/lint/check-no-backwards-deps.ts)
enforces the rule on every commit:
```bash
bun scripts/lint/check-no-backwards-deps.ts \
--package-json packages/react/react-i18n/package.json
```
The script is wired into `package.json`'s `lint` step so
`bunx turbo lint --filter=@suaveplan/react-i18n` fails fast if a banned
dep ever lands.
## Telemetry
OTel instruments published via `getMeter("suaveplan.react-i18n")`:
- Counter `react_i18n.missing_key.total` — labels: `locale`,
`namespace`, `componentName?`. Incremented from `<Trans>` (and
`tDynamic`) when a key is absent from the catalog.
- Counter `react_i18n.suspense.fallback.total` — labels: `namespace`,
`locale`. Incremented every time `<I18nSuspense>` renders its
default fallback.
- Histogram `react_i18n.render.duration_ms` — labels: `locale`,
`namespace`, `componentName?`. Recorded around the `<Trans>`
`formatChunks` render.
- Counter `i18n.detector.match_total{detector}` — recorded by every
detector when it returns a non-null supported locale.
- Histogram `i18n.detector.duration_ms{detector}` — recorded for each
`detectAsync` call.
- Span `i18n.detect` — wraps the entire chain run; carries
`winning_detector` and `resolved_locale` attributes.
The `tDynamic` call's per-use `warn` log is NOT OTel — it goes to the
`@suaveplan/logger` sink and surfaces in centralised log aggregation.
## E2E sweep
The Playwright suite at
[`e2e/react-i18n.spec.ts`](./e2e/react-i18n.spec.ts) runs against a
tiny Vite + React test app at
[`e2e/test-app/`](./e2e/test-app/) and covers the five user-visible
behaviours:
1. Live language switch through all five locales (`en-GB`, `ar-AE`,
`zh-CN`, `cy-GB`, `ru-RU`) with localStorage persistence.
2. RTL flip on Arabic — `<html dir="rtl">` updates and the layout
reflows.
3. Lazy-namespace Suspense — the `<I18nSuspense>` fallback resolves
to translated content via the async test backend.
4. Missing-key overlay (dev mode) — caps at 50 entries with
`aria-live="polite"`.
5. SSR hydration round-trip — the server-rendered HTML already
contains the translated string (no flash) and the client hydrates
without a React warning.
Per `CLAUDE.md` "Web App & Page Verification": every scenario also
asserts (a) zero browser-console errors, (b) zero failed network
requests (4xx/5xx), and (c) the rendered DOM contains the expected
content (not merely a 200 response).
```bash
bunx turbo lint typecheck test:coverage build --filter=@suaveplan/react-i18n
bun --cwd packages/react/react-i18n test:e2e
```
## Testing
```bash
bunx turbo lint typecheck test --filter=@suaveplan/react-i18n
bunx turbo test:coverage --filter=@suaveplan/react-i18n
```
Coverage targets: 100/100/100/100 (statements / branches / functions /
lines) per `CLAUDE.md` §"Quality". The thresholds are wired into
`vitest.config.ts`. The pre-publish gate also runs the full §13
verification sequence — see `AGENTS.md` for the canonical
checklist.
## License
MIT.