I18n
GPUI Component includes translations for its components, currently en, zh-CN, and zh-HK. Applications can add a language or override individual translations without copying the complete built-in locale files.
This feature requires rust-i18n 4.2 or later.
Add the dependency
Add rust-i18n to the application crate that owns your locale files:
[dependencies]
gpui-component = "0.5"
rust-i18n = "4.2"Create an application locale file
Create locales/ui.yml in your application crate. Put component translations under the gpui_component namespace:
_version: 2
gpui_component:
Calendar:
week.0:
fr: Di
month.January:
fr: Janvier
DatePicker:
placeholder:
fr: Sélectionner une dateThe namespace must be gpui_component, matching the Rust crate name gpui-component with hyphens converted to underscores. Translation keys can be found in GPUI Component's built-in locale file.
Register the extension
Initialize the application's locales at the crate root:
rust_i18n::i18n!("locales", fallback = "en");Register them before initializing GPUI Component:
app.run(move |cx| {
rust_i18n::extend!(gpui_component);
gpui_component::init(cx);
// Open windows and initialize the rest of the application.
});Call extend! only once during application startup.
Lookup priority
The application's translations take priority over the component's built-in translations:
Application locales (locales/ui.yml)
│
│ key not found
▼
GPUI Component built-in localesThis deep-merge behavior means that:
- A new locale, such as
fr, can contain only the keys your application needs. - A translation with the same locale and key overrides the built-in value.
- Keys not supplied by the application continue to use the built-in value.
- Future GPUI Component translations remain available without being copied into the application.
For example, defining only gpui_component.Calendar.month.January.en changes January's English label while all other English calendar labels still come from GPUI Component.
The namespace applies to component lookups only
extend! changes how GPUI Component resolves its keys. It does not give the application's own t! calls access to the built-in translations:
// Inside a GPUI Component component: application value first, built-in second.
t!("Calendar.month.February") // -> "February"
// In application code: reads the application's locale files only.
t!("gpui_component.Calendar.month.February") // -> the key, unless you defined itRead component strings by rendering the component, not by looking the key up yourself.
Select a locale
gpui-component re-exports the locale accessors, so an application does not have to reach for rust-i18n to switch languages:
gpui_component::set_locale("fr");
let current = gpui_component::locale();Components then resolve their translated labels using the selected locale and the priority described above.
The active locale is global state that GPUI does not track, so changing it does not schedule a repaint on its own. A view that displays translated text must notify itself:
gpui_component::set_locale("fr");
cx.notify();