657 lines
75 KiB
Markdown
657 lines
75 KiB
Markdown
# @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.
|
|
|