Internationalization (i18n)
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Vata application implements a comprehensive Internationalization (i18n) system designed to support multiple languages and ensure that all user-facing strings are localized. The project follows an "English Only" development policy for code and documentation, but requires all client-facing strings—such as UI labels, button text, and error messages—to be externalized into translation files.
The system is built on the i18next ecosystem, utilizing React bindings for component-level integration. It supports language detection via browser settings and local storage overrides, allowing the application to persist user language preferences across sessions.
Sources: CLAUDE.md:144-152, src/i18n/config.ts:36-41
Core Architecture
The i18n architecture is centralized around a configuration module that initializes the translation engine and manages resource namespaces.
Tech Stack and Libraries
The i18n implementation relies on the following dependencies:
- i18next: The core translation framework.
- react-i18next: React hooks and components for translation.
- i18next-browser-languagedetector: Utility for detecting the user's preferred language.
Sources: package.json:54-56, src/i18n/config.ts:1-3
Localization Logic Flow
The application detects the language on startup and loads the corresponding JSON resources.
The detection order prioritizes localStorage (key: vata-language) followed by the browser's navigator settings.
Sources: src/i18n/config.ts:36-41
Configuration and Implementation
Initialization Settings
The system is configured in src/i18n/config.ts. It supports English (en) and French (fr) as the primary languages.
| Option | Value | Description |
|---|---|---|
supportedLngs | ['en', 'fr'] | The languages available in the app. |
fallbackLng | 'en' | Default language if detection fails. |
defaultNS | 'common' | Default namespace for translations. |
interpolation | { escapeValue: false } | Disables escaping (React handles XSS). |
Sources: src/i18n/config.ts:5-7, src/i18n/config.ts:31-43
Resource Namespaces
Translations are organized into logical namespaces to prevent large, monolithic files and improve maintainability.
| Namespace | Usage |
|---|---|
common | Shared UI elements (Nav, App title, Debug, Preferences). |
trees | Tree management and GEDCOM import/export strings. |
individuals | Person-specific labels and forms. |
families | Relationship and family record strings. |
events | Life event (Birth, Death, etc.) labels. |
places | Geographical and location-based strings. |
Sources: src/i18n/config.ts:9-29, src/i18n/locales/en/common.json
Usage in Components
Developers use the useTranslation hook to access localized strings within React components.
Implementation Pattern
Strings are accessed via a key-based system using the t() function. For example, in the ImportGedcomModal, the hook is initialized with the trees namespace:
const { t } = useTranslation('trees');
Components then reference specific keys:
t('importGedcom.title')t('importGedcom.dropzoneScanning', { name: scanning })(using interpolation)
Sources: src/components/trees/import-gedcom-modal.tsx:103, src/components/trees/import-gedcom-modal.tsx:192-205
User Preferences UI
The application provides a preferences interface to allow users to manually toggle between supported languages. This interaction updates the vata-language key in local storage.
Developer Guidelines
The project enforces strict rules regarding string literals to ensure the application remains localizable:
- Never Hardcode: All client-facing strings (labels, buttons, placeholders, toasts) must use
t(). - Out of Scope: Test files and developer-only debug UIs (guarded by
import.meta.env.DEV) may use string literals. - Language: All internal documentation, code comments, and variable names must remain in English.
Sources: CLAUDE.md:144-168
Conclusion
The i18n system in Vata provides a robust foundation for a multi-lingual desktop experience. By leveraging i18next and a structured namespace approach, the application separates content from logic, allowing for easy expansion to additional languages while maintaining the strict local-first architectural requirements of the project.