vojo/docs/ai/i18n.md

3.8 KiB

Localisation (i18n)

Setup

  • Config: 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/ru.json
  • Namespaces (top-level keys in the JSON files): Organisms, Auth, Settings, Search, Home, Direct, Room, Inbox, Explore, Create, RoomSettings, Push

Usage pattern

import { useTranslation } from 'react-i18next';

const { t } = useTranslation();
return <Text>{t('RoomSettings.some_key')}</Text>;

Dynamic values:

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.