73 lines
3.8 KiB
Markdown
73 lines
3.8 KiB
Markdown
# Localisation (i18n)
|
|
|
|
## Setup
|
|
|
|
- **Config**: [`src/app/i18n.ts`](../../src/app/i18n.ts) — i18next + HTTP backend + language detector
|
|
- **Fallback language**: `en` (lingua franca for unsupported detected locales; keeps web/SW/Android push surfaces aligned — see §5.27 in docs/plans/dm_calls_techdebt.md)
|
|
- **Supported languages**: `en`, `ru` (set in `supportedLngs`; anything else normalises to `en`)
|
|
- **Locale files**: [`public/locales/en.json`](../../public/locales/en.json), [`public/locales/ru.json`](../../public/locales/ru.json)
|
|
- **Namespaces** (top-level keys in the JSON files): `Organisms`, `Auth`, `Settings`, `Search`, `Home`, `Direct`, `Room`, `Inbox`, `Explore`, `Create`, `RoomSettings`, `Push`
|
|
|
|
## Usage pattern
|
|
|
|
```tsx
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
const { t } = useTranslation();
|
|
return <Text>{t('RoomSettings.some_key')}</Text>;
|
|
```
|
|
|
|
Dynamic values:
|
|
```tsx
|
|
t('key', { count: 5 })
|
|
```
|
|
|
|
For the rare case where a translation contains HTML tags, use `dangerouslySetInnerHTML` (used sparingly, e.g. in `RoomAddress.tsx`).
|
|
|
|
## Conventions
|
|
|
|
- Every React component gets its own `useTranslation()` call — do not share `t` across components.
|
|
- Custom hooks with `useMemo` / `useCallback` must include `t` in their dependency array. This is what makes language switching actually re-render.
|
|
- Import order: `react-i18next` goes after framework imports (`react`, `folds`, `focus-trap-react`, …) and before local imports.
|
|
- After adding `useTranslation` inside a hook, always run `npm run lint` / check `exhaustive-deps` warnings.
|
|
|
|
## Russian translation quality standards
|
|
|
|
The developer reviews Russian translations as a native speaker would see them in UI context, and has specifically called out the following past failures:
|
|
|
|
- **Buttons are verbs, not nouns.** "Открыть" (not "Просмотр") for a View button. "Создать" (not "Создание"). Action labels in Russian must be infinitive or imperative verb forms.
|
|
- **Avoid calques from English.** "публичный каталог" sounds translated; "общий список" reads naturally. If a phrase feels like literal English in Cyrillic, rewrite it.
|
|
- **Kill ambiguous pronouns.** Passive constructions like "могут быть изменены" leave the reader asking *who/what is being changed*. Rewrite with an explicit subject.
|
|
- **Read it in context.** Translations are for UI, not documentation. Short, unambiguous, natural.
|
|
|
|
**Why this matters:** These came from real review corrections ("Просмотр" for a button, "Составить" for Compose, ambiguous `founders_desc`). The developer is Russian-native and will notice.
|
|
|
|
## Localisation progress
|
|
|
|
**Completed namespaces** (fully localised EN + RU):
|
|
|
|
- `Auth` — Login, register, password reset
|
|
- `Settings` — All user-settings sections
|
|
- `Search` — Global search
|
|
- `Home` — Home timeline
|
|
- `Direct` — DM list
|
|
- `Room` — Room UI
|
|
- `Inbox` — Notifications & invites
|
|
- `Explore` — Public rooms
|
|
- `Create` — Room/space creation
|
|
- `RoomSettings` — Room settings (general, members, permissions, emojis/stickers, developer tools, image pack editor, power level tags)
|
|
- `Organisms` — Complex UI pieces
|
|
|
|
**Still to localise** (snapshot taken 2026-04-14 — verify before acting):
|
|
|
|
- Room features: `MessageEditor`, `MembersDrawer`, `RoomTombstone`
|
|
- Lobby: `Lobby.tsx`, `RoomItem.tsx`
|
|
- `AddExisting` feature
|
|
- System pages: `ConfigConfig`, `FeatureCheck`, `SpecVersions`, `WelcomePage`, `ClientRoot`
|
|
- Auth: `OrDivider`
|
|
- Dialogs: `LogoutDialog`, `ManualVerification`, `BackupRestore`
|
|
- UIA stages: `ReCaptchaStage`, `EmailStage`, `RegistrationTokenStage`
|
|
- Components: `TimePicker`, `DatePicker`, `ImageViewer`, `PdfViewer`, `UploadCard`, `UserModeration`
|
|
- Various `aria-label` attributes throughout
|
|
|
|
When the developer asks to localise a new area, check this list first and update it after finishing.
|