This page covers the internationalization (i18n) system for Clash Verge Rev: how the UI language is detected, stored, loaded, and consumed by frontend components. It does not cover the theming system (see 4.2) or general settings persistence (see 2.3).
The i18n system spans both the Rust backend and the TypeScript frontend:
verge.yaml.react-i18next and exposes translations through the useTranslation hook.The selected language is stored in verge.yaml as the language field on the IVerge struct.
src-tauri/src/config/verge.rs25-26
When no configuration exists, IVerge::template() seeds the default value by calling clash_verge_i18n::system_language(), which reads the host OS locale and maps it to one of the supported language codes.
src-tauri/src/config/verge.rs379-384
The language field is treated like any other IVerge setting: it is patched through patch_config, persisted via save_file, and propagated to the frontend when settings are read.
src-tauri/src/config/verge.rs472
System language detection flow
Sources: src-tauri/src/config/verge.rs25-26 src-tauri/src/config/verge.rs379-384
The four supported language codes (as returned by clash_verge_i18n::system_language() or selected by the user) are:
| Language | Code | Direction |
|---|---|---|
| English | en | LTR |
| Simplified Chinese | zh | LTR |
| Russian | ru | LTR |
| Persian (Farsi) | fa | RTL |
The frontend uses the react-i18next library. Each component that needs translated text imports useTranslation and destructures the t function.
src/components/setting/mods/layout-viewer.tsx18 src/components/setting/mods/layout-viewer.tsx52
Frontend i18n component relationships
Sources: src/components/setting/mods/layout-viewer.tsx18-52
All translation keys use dot-separated hierarchical paths. Based on keys observed in component code, the top-level namespaces are:
| Namespace | Purpose |
|---|---|
shared | Reusable strings (actions, units, status labels) |
settings | Settings page labels and option values |
proxy | Proxy group and node-related strings |
profile | Profile management UI strings |
log | Log viewer UI strings |
connection | Connections page strings |
rule | Rules page strings |
Key hierarchy example — settings namespace
Key hierarchy example — shared namespace
Sources: src/components/setting/mods/layout-viewer.tsx114-628
The standard pattern for consuming translations in any component:
Translation keys are always string literals passed directly to t(). There is no runtime key construction in the component layer.
Sources: src/components/setting/mods/layout-viewer.tsx18 src/components/setting/mods/layout-viewer.tsx52 src/components/setting/mods/layout-viewer.tsx143-147
The user can change the language in the Settings UI. The selection is persisted by patching IVerge.language through the standard patchVerge flow (see 2.3), which writes to verge.yaml. The frontend then calls i18n.changeLanguage() with the new value, and react-i18next re-renders all components that depend on translated strings without requiring an application restart.
<code>.json file in src/locales/ matching one of the BCP 47 language tags.clash_verge_i18n Rust crate's language mapping so system_language() can return the correct code when the OS reports that locale.en.json) and translate each value string, preserving the exact key hierarchy.MenuItem in the language selector component inside the Settings page so users can select it.dir attribute is set appropriately in the i18n initialization or the HTML root element.Sources: src-tauri/src/config/verge.rs383-384 src/components/setting/mods/layout-viewer.tsx18-52
Refresh this wiki