---
id: i18n
title: i18n (8 locales)
category: frontend
level: mandatory
applies_to:
  - frontend-page
status: active
version: 1.0.0
last_reviewed: 2026-04-19
owners:
  - frontend-team
---

# i18n (8 locales)

## Purpose

Every user-facing string is translated in 8 locales: EN, AR, DE, ES, FR, IT, PT, RU. Arabic is RTL. Hardcoded English is a bug.

## Workflow

1. Add the English key to `src/lib/i18n/locales/en.ts` at the appropriate nesting depth.
2. Add the same key to `ar.ts`, `de.ts`, `es.ts`, `fr.ts`, `it.ts`, `pt.ts`, `ru.ts`.
3. Update `src/types/i18n.types.ts` with the new shape so TypeScript catches omissions.
4. Use `const { t } = useTranslation()` in the controller hook, pass `t` down as prop.
5. For nested keys, use dots: `t('discovery.filter.pending')`.
6. Test in Arabic mode — confirm RTL renders correctly.

## Strict rules

- **MUST** add keys to ALL 8 locales. **BLOCKER** if any locale is missing.
- **MUST** update `i18n.types.ts`.
- **MUST** use `t()` — no hardcoded user-facing strings.
- **MUST** test Arabic RTL for layout-sensitive UI.

## Anti-patterns

- `<Button>Submit</Button>` — should be `t('common.submit')`.
- Adding to `en.ts` only, "other locales later".
- Forgetting to update `i18n.types.ts`.

## Validation checklist

- [ ] Key in all 8 locale files
- [ ] `i18n.types.ts` updated
- [ ] No hardcoded strings in TSX
- [ ] Arabic RTL tested

## Quality gate

| Check                           | Blocker? | Evidence     |
| ------------------------------- | -------- | ------------ |
| Typecheck passes                | yes      | CI           |
| 8 locale files all have the key | yes      | grep         |
| Arabic UI renders RTL correctly | yes      | Manual check |

## Definition of done

1. All 8 locales have the key.
2. Types updated.
3. Arabic verified.

## Examples

- PR adding `discovery` keys to all 8 locales.

## References

- `apps/claw-frontend/src/lib/i18n/translations.ts` (nested key resolver)
