# 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