feat(i18n): add runtime-switchable language support#176
Open
srsholmes wants to merge 1 commit into
Open
Conversation
Introduce an internationalization mechanism for the overlay app and its plugins, with runtime language switching and per-plugin translation files. Core (shared singleton in @loadout/ui): - Add i18next + react-i18next; new packages/ui/src/i18n.ts hosts one i18next instance. Because plugin bundles resolve @loadout/ui to the shell's __LOADOUT_SDK global, the shell and every plugin share that instance — setLanguage() re-renders the whole tree with no reload. - Expose initI18n, setLanguage, ensureNamespace, normalizeLocale, usePluginTranslation, SUPPORTED_LANGUAGES (en-gb, zh-cn) and DEFAULT. Detection / persistence / override: - First-run detection: host OS locale (new getSystemLocale RPC) -> navigator.language -> English, normalized to a supported code and persisted under the `language` user-config key. - Settings > General gains a Language selector that switches at runtime. Translation files: - Shell strings live under the `app` namespace in apps/loadout-overlay/src/overlay/i18n/<code>.json (statically bundled). - Plugins ship an i18n/<code>.json folder (flat key/value, one file per language, plugin id = namespace), served by the loader at /plugins/<id>/i18n/<code>.json and lazy-loaded on first use; missing keys fall back to English. Proof of mechanism (full English source + partial Chinese): - Wire the Settings screen and the battery-tracker plugin to t() keys. - This PR is the mechanism only; bulk translation is left to a follow-up. Docs + tests: - Document the convention in CLAUDE.md. - Unit-test normalizeLocale; keep battery-tracker spec green by resolving its assertions against the shipped en-gb.json. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01XEKUyS4sptP4hoLgKCDxxu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduce an internationalization mechanism for the overlay app and its
plugins, with runtime language switching and per-plugin translation files.
Core (shared singleton in @loadout/ui):
i18next instance. Because plugin bundles resolve @loadout/ui to the
shell's __LOADOUT_SDK global, the shell and every plugin share that
instance — setLanguage() re-renders the whole tree with no reload.
usePluginTranslation, SUPPORTED_LANGUAGES (en-gb, zh-cn) and DEFAULT.
Detection / persistence / override:
navigator.language -> English, normalized to a supported code and
persisted under the
languageuser-config key.Translation files:
appnamespace inapps/loadout-overlay/src/overlay/i18n/
.json (statically bundled)..json folder (flat key/value, one file perlanguage, plugin id = namespace), served by the loader at
/plugins//i18n/
.json and lazy-loaded on first use; missingkeys fall back to English.
Proof of mechanism (full English source + partial Chinese):
Docs + tests:
its assertions against the shipped en-gb.json.
Co-Authored-By: Claude Opus 4.8 [email protected]
Claude-Session: https://claude.ai/code/session_01XEKUyS4sptP4hoLgKCDxxu