Custom i18n system with typed translation dictionaries (~570 keys), LanguageProvider context, and useTranslation hook. All 31 components and pages wired with t() calls. Chatbot backend passes language hint to Claude for Ukrainian responses. Language preference persists via localStorage. SEO meta tags and html lang attribute update dynamically. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1.9 KiB
1.9 KiB
Data Model: Multi-Language Support
Entities
Language
A supported language for the site UI.
| Field | Type | Description |
|---|---|---|
| code | 'en' | 'uk' |
ISO 639-1 language code |
| displayLabel | string |
Label shown in toggle ("Eng", "Ukr") |
| locale | string |
Full locale for date formatting ("en-GB", "uk-UA") |
Supported languages (hardcoded, no dynamic loading):
- English:
{ code: 'en', displayLabel: 'Eng', locale: 'en-GB' } - Ukrainian:
{ code: 'uk', displayLabel: 'Ukr', locale: 'uk-UA' }
Translations
A typed dictionary mapping translation keys to localized strings.
| Field | Type | Description |
|---|---|---|
| [key: TranslationKey] | string |
Translated text for the given key |
TranslationKey is a union type of all valid dot-separated keys (e.g., 'header.nav.home' | 'hero.title' | ...).
Both en.ts and uk.ts must satisfy the Translations type — TypeScript enforces that no keys are missing.
Language Preference (Client-Side)
| Storage | Key | Type | Default |
|---|---|---|---|
| localStorage | aimpress_lang |
'en' | 'uk' |
'en' |
Read on app initialization. Updated on language toggle. No server-side persistence.
State Transitions
First Visit → lang = 'en' (default)
↓
User clicks 'Ukr' → lang = 'uk', localStorage set
↓
User clicks 'Eng' → lang = 'en', localStorage set
↓
Return Visit → lang = localStorage value (or 'en' if cleared)
Relationships
LanguageContextholds currentLanguageand providest()functiont(key)resolves against current language'sTranslationsdict, falls back to EnglishChatRequestbody includeslanguagecode for backend AI responses- Date formatting uses
Language.localeviaIntl.DateTimeFormat <html lang>attribute set fromLanguage.code