# 013 — Frontend i18n (react-i18n-lite)

**Status:** Implemented  
**Created:** 2026-06-04

## Objective

Internationalize the web UI in English (`en-US`) and Spanish (`es-ES`) using [react-i18n-lite](https://www.npmjs.com/package/react-i18n-lite).

## Architecture

```
App.tsx
  └── I18nProvider (TranslationContainer)
        ├── resolveDefaultLanguage() — localStorage → navigator → en-US
        ├── LanguagePersistence — sync setLanguage ↔ localStorage, html[lang]
        └── AuthProvider → ToastProvider → routes
```

Components call `useTranslation()` and `t('namespace.key', { interpolation })`.

## Locale files

| File | Purpose |
|------|---------|
| `frontend/src/locales/en-US.ts` | English dictionary |
| `frontend/src/locales/es-ES.ts` | Spanish dictionary |
| `frontend/src/locales/index.ts` | `locales` map, `SupportedLanguage`, helpers |

Key namespaces: `common`, `auth`, `library`, `contextMenu`, `toast`, `settings`, `reader`, `addBook`, `bookDetail`, `search`, `annotations`.

## Language selection

- **Settings page** — UI Language dropdown (English / Español)
- **Persistence** — `localStorage` key `cloud-reader.locale`
- **Default** — saved preference, else `navigator.language` (`es*` → `es-ES`), else `en-US`

## Scope

**Translated:** All user-facing chrome (library, auth, reader toolbar/settings/TOC, add book, book detail, annotations, context menu, toasts).

**Not translated:** EPUB body content, API error bodies, backend `reading_status_display`, Open Library metadata fields.

## Dependencies

- `react-i18n-lite` (^1.0.10)

## Verification

1. Open app — labels match browser or saved language
2. Settings → switch to Español — library/auth update without reload
3. Refresh — language persists
4. Context menu and toasts show translated strings
5. `yarn build` succeeds
