Internationalization (i18n)
CheckAI supports 8 languages out of the box with full coverage of all user-facing strings in both the backend and the web frontend.
Supported Languages
| Code | Language |
|---|---|
en | English (default) |
de | German |
fr | French |
es | Spanish |
zh-CN | Chinese (Simplified) |
ja | Japanese |
pt | Portuguese |
ru | Russian |
Backend (Rust)
The backend uses the rust-i18n crate with YAML locale files.
Locale Files
Translations are stored in locales/*.yml:
locales/
├── en.yml
├── de.yml
├── fr.yml
├── es.yml
├── zh-CN.yml
├── ja.yml
├── pt.yml
└── ru.ymlUsage in Code
use rust_i18n::t;
// Simple key lookup
let msg = t!("game.created");
// With interpolation
let msg = t!("game.move_made", from = "e2", to = "e4");Locale Resolution
--langCLI flagCHECKAI_LANGenvironment variable- System locale (auto-detected via
sys-locale) - Fallback: English
Per-Request Locale (API)
API requests can specify a locale:
# Query parameter
GET /api/games?lang=de
# Accept-Language header
GET /api/games
Accept-Language: deFrontend (Web UI)
The web frontend has its own translation module at web/src/i18n.ts with ~120 keys per language embedded inline.
Features
- Auto-detection from browser
navigator.language - Language selector dropdown in the header (dynamically populated)
- Persistence via
localStorage(key:checkai-locale) data-i18nattributes for declarative HTML translationsdata-i18n-placeholderanddata-i18n-titlefor inputs and tooltipst()function for programmatic access with%{name}interpolation
Adding a New Language
To add a new language (e.g. Italian):
1. Backend — add a YAML locale file:
Create locales/it.yml following the structure of locales/en.yml:
it:
game.created: "Nuova partita creata. Il Bianco muove."
game.move_made: "Mossa da %{from} a %{to}"
# ... translate all keys from en.ymlThe rust-i18n crate picks up new YAML files automatically.
2. Frontend — add translations to the DICTIONARIES object:
In web/src/i18n.ts, add a new entry:
it: {
'app.title': 'CheckAI — Scacchi per agenti IA',
'nav.dashboard': 'Pannello',
// ... translate all keys
},3. Register the locale in SUPPORTED_LOCALES:
export const SUPPORTED_LOCALES: LocaleInfo[] = [
// ...existing locales
{ code: 'it', name: 'Italiano' },
];The language selector will automatically include the new language.