49 lines
1.6 KiB
Markdown
49 lines
1.6 KiB
Markdown
## i18n Guide
|
|
|
|
Readest uses a **key-as-content** approach — English strings are the translation keys. The English locale (`en/translation.json`) is empty because keys serve as content. Other locales contain actual translations.
|
|
|
|
### In React Components
|
|
|
|
```tsx
|
|
import { useTranslation } from '@/hooks/useTranslation';
|
|
|
|
const _ = useTranslation();
|
|
_('Progress synced');
|
|
```
|
|
|
|
### In Non-React Modules
|
|
|
|
Two-step process:
|
|
|
|
**1. Declaration** — Use `stubTranslation` to mark strings for scanner extraction (returns key as-is, does NOT translate):
|
|
|
|
```ts
|
|
import { stubTranslation as _ } from '@/utils/misc';
|
|
|
|
// These calls only register keys for extraction
|
|
_('Reveal in Finder');
|
|
_('Reveal in Explorer');
|
|
```
|
|
|
|
**2. Usage** — In the React component that consumes the value, apply the real `_()` from `useTranslation`:
|
|
|
|
```tsx
|
|
const _ = useTranslation();
|
|
const label = _(getRevealLabel()); // translates at runtime
|
|
```
|
|
|
|
### Extraction & Translation
|
|
|
|
```bash
|
|
pnpm i18n:extract # Scans codebase, adds new keys with __STRING_NOT_TRANSLATED__
|
|
```
|
|
|
|
- Translation files: `public/locales/<locale>/translation.json`
|
|
- Only `_('KEY')` and `_('KEY', options)` patterns are recognized by i18next-scanner
|
|
|
|
### Rules
|
|
|
|
- `stubTranslation` is for extraction only — always apply `_()` from `useTranslation` in the component for runtime translation.
|
|
- Fallback: when no translation exists, the English key itself is displayed.
|
|
- Error messages: register keys with `stubTranslation` in utility modules (e.g. `src/services/errors.ts`), return the English key from helpers, wrap with `_()` in the component.
|