# Localization The web interface uses JSON language packs from `lang/`. Language files are discovered at Rust build time and embedded in the application binary. English (`lang/en.json`) is required and is always the fallback language. Polish (`lang/pl.json`) is included by default. ## Add a language 1. Copy `lang/en.json` to a file named with the new language code, for example `lang/de.json`. 2. Update the `meta` object. 3. Translate values inside `translations`. Do not rename translation keys. 4. Run `./scripts/dev.sh --check` or build the project again. 5. Start the rebuilt binary. The new language appears automatically in the language selector. Example structure: ```json { "meta": { "code": "de", "name": "German", "native_name": "Deutsch", "locale": "de-DE" }, "translations": { "controls.language": "Sprache", "controls.theme": "Darstellung" } } ``` The filename and `meta.code` must match (`de.json` -> `"code": "de"`). File names may contain ASCII letters, digits, `-` and `_` only. ## Fallback behavior A language pack does not have to duplicate every English key while it is being developed. If a key is missing from the selected language, the UI uses the value from `en.json`. If a key is also missing from English, the translation key itself is shown, which makes incomplete strings visible during development. ## Build-time validation `build.rs` checks that: - at least one JSON language file exists, - `en.json` exists, - every language file contains valid JSON, - every file has `meta.code`, `meta.name`, `meta.native_name` and `meta.locale`, - `meta.code` matches the filename, - `translations` is a JSON object. A malformed language pack fails the Rust build instead of producing a broken selector at runtime. ## Runtime endpoints The embedded language catalog is available at: ```text GET /lang/index.json ``` Individual embedded packs are available at: ```text GET /lang/en.json GET /lang/pl.json GET /lang/.json ``` These endpoints are intentionally public so that localization also works before API authentication is completed. ## Browser preference The selected language code is stored for one year in the `gree_controller_language` cookie. If the stored language is no longer present in a later build, the UI falls back to English.