How i18n Works in App Shell
App Shell provides two levels of internationalization:- Built-in UI strings - Navigation, command palette, error messages (English and Japanese included)
- Your application strings - Module titles, page content, custom labels (you define these)
- Explicit
localeprop onAppShell(if provided) - Browser language detection (if no prop provided)
- Fallback to English if the detected language isn’t supported
Quick Start
Setting the Locale
en- English (default)ja- Japanese
"fr", "de"), but built-in UI strings will fall back to English. Your custom labels defined with defineI18nLabels will work with any locale.
Defining Custom Labels
UsedefineI18nLabels to create type-safe translations for your application:
Create a Labels File
Create
i18n-labels.ts to define your translations:The
en locale is required and serves as the fallback for any missing translations.Dynamic Label Keys
For runtime-determined label keys (like status badges), uset.dynamic():
t.dynamic() is the fallback text if the key doesn’t exist.
Switching Locales at Runtime
Allow users to change the language:Real-World Example
Here’s a complete example from the App Shell source code:Built-in UI Translations
App Shell includes these built-in translations:| Key | English | Japanese |
|---|---|---|
error404Title | 404 Not Found | 404 ページが見つかりません |
error404Body | The page you requested could not be found. | お探しのページは存在しません。 |
goBack | Go Back | 戻る |
settings | Settings | 設定 |
toggleSidebar | Toggle Sidebar | サイドバーを切り替え |
commandPaletteSearch | Search pages… | ページを検索… |
commandPaletteNoResults | No results found | 結果が見つかりません |
locale prop.
Advanced Patterns
Pluralization
Handle singular and plural forms:Nested Translations
Organize labels with dot notation:Date and Number Formatting
Use browser APIs for locale-aware formatting:Best Practices
Organization
- Keep all labels in a single
i18n-labels.tsfile - Use consistent naming:
"module.resource.label" - Group related labels together
- Document complex pluralization rules
Translation Quality
- Work with native speakers for accurate translations
- Keep strings short and context-independent
- Avoid hard-coded punctuation (it varies by language)
- Test with real content, not placeholder text
Type Safety
Performance
- Labels are loaded once and cached
- No runtime overhead for static strings
- Dynamic functions are memoized per locale
Limitations
- Built-in UI strings only support English and Japanese
- No automatic RTL (right-to-left) layout support
- Date/time formatting requires manual integration with
IntlAPIs