feat(i18n): translatable UI with on-demand language catalogs - #118
Merged
Conversation
This was referenced Jun 28, 2026
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.
Makes the interface translatable, with languages delivered on demand so the
binary stays English-only and new translations ship without a release.
The translation layer
t(key, params)andtn(key, count, params)resolve UI text against the activelocale, with
{placeholder}interpolation andIntl-based plural rules.only some keys shows English for the rest.
saved choice, then the browser language, then English.
On-demand catalogs
GET /api/i18nandGET /api/i18n/{locale}proxy the catalog files from therepo over a CDN, so a translation can be published or corrected without a new
build. The browser talks only to the backend, which avoids CORS and works when
outbound network is backend-only.
hours; a failed refresh still serves a stale cached copy. The locale tag is
bounded so it can't reach another path or host.
Coverage
layer. Label lists that were built once (table headers, nav, command palette,
status pills) are reactive, so text updates on a language switch without reload.
Only English ships here; this is the machinery plus the English catalog. Strings
the backend produces (error text, raw engine states) are still shown as received.
Testing
rejection, and tag validation.
npm run build,go build ./..., andgo test ./...pass.