Files
simple-react-app-kit/packages/ui/docs/en-US/advanced/localization.mdx
T

81 lines
3.1 KiB
Plaintext
Raw Normal View History

---
title: Localize UI
2026-09-21 17:27:45 +08:00
description: Bridge the application translator into UI components and load the active calendar locale.
order: 21
toc:
2026-09-21 17:27:45 +08:00
- id: two-layers
title: Two responsibilities
- id: catalogs
title: Merge catalogs
- id: bridge-provider
title: Bridge the provider
- id: fallback
title: Fallback behavior
- id: direction
title: Text direction
---
2026-09-21 17:27:45 +08:00
## Two responsibilities {#two-layers}
2026-09-21 17:27:45 +08:00
`@workspace/i18n` manages the application locale, catalog loading, formatting, and switching. `@workspace/ui/components/i18n` is a small adapter that keeps UI primitives independent of an internationalization framework. It accepts a compatible translator, a language tag, and a `react-day-picker` locale.
This separation keeps the UI package reusable while allowing applications to use the full workspace internationalization runtime.
## Merge catalogs {#catalogs}
Add the UI catalog source to the application's `i18n.config.json`:
```json
{
"catalogSources": ["@workspace/ui/locales/{locale}"]
}
```
2026-09-21 17:27:45 +08:00
The `@workspace/ui/locales` root exports only `uiCatalogLocales`, `uiMessageIds`, and types; it does not statically import every language. The current supported set is `en-US` and `zh-Hans`.
## Bridge the provider {#bridge-provider}
Read the translator from the current application provider and pass it to the UI provider:
```tsx
import { useLocaleDefinition, useTranslate } from "@workspace/i18n"
import {
I18nProvider as UiI18nProvider,
type CalendarLocale,
} from "@workspace/ui/components/i18n"
import { calendarLocale as enUS } from "@workspace/ui/locales/en-US"
import { calendarLocale as zhHans } from "@workspace/ui/locales/zh-Hans"
2026-09-21 17:27:45 +08:00
const calendarLocales: Record<string, CalendarLocale> = {
"en-US": enUS,
"zh-Hans": zhHans,
}
export function AppUiI18nProvider({ children }: React.PropsWithChildren) {
const locale = useLocaleDefinition()
const t = useTranslate()
2026-09-21 17:27:45 +08:00
return (
<UiI18nProvider
calendarLocale={calendarLocales[locale.locale]}
locale={locale.languageTag ?? locale.locale}
t={t}
>
{children}
</UiI18nProvider>
)
}
```
2026-09-21 17:27:45 +08:00
`Calendar` prefers its own `locale` prop, then the provider's `calendarLocale`. Month formatting and the default `lang` use the provider language tag.
## Fallback behavior {#fallback}
Without a provider, the UI layer uses `en-US` and the English source text from each descriptor. Isolated tests and stories therefore remain usable, but production applications should bridge the provider so accessible names and visible text use the same locale.
Custom components may use `uiMessages`, `useMessage`, `useTranslate`, `LocalizedText`, `useLocale`, and `useCalendarLocale`. Product copy belongs in the application or domain package, not in the UI catalog.
2026-09-21 17:27:45 +08:00
## Text direction {#direction}
2026-09-21 17:27:45 +08:00
Translation locale and layout direction are separate concerns. When switching locales, the application should synchronize `document.documentElement.lang` and `dir`, and use `DirectionProvider` when needed. Local components use logical utilities such as `start`, `end`, `ps`, and `pe`; `components.json` also enables `rtl` generation.