Switch the interface between English and Spanish - #17
Merged
Conversation
The analysis has been bilingual since the MVP, but the chrome around it was English-only —
a wall in front of half the audience this is built for.
A segmented EN/ES control in the toolbar now flips the whole interface instantly, with no
page reload. The choice is remembered per browser and follows the browser's own language on
a first visit.
Translations are plain JSON in wwwroot/i18n, listed in a locales.json manifest, rather than
a compiled string table or satellite .resx assemblies. Adding a language has to be something
a translator can do without a compiler — the same reason the rule packs are JSON. A locale is
one file plus one manifest line, and the switch renders it with no code change. Missing keys
fall back to English, so a partial contribution is mergeable instead of leaving blanks, and
contributors are credited on the switch itself.
Findings deliberately stay in the language of the analyzed text: advice about English prose is
given in English even with a Spanish interface, because that is the language it describes.
Six locale tests guard the files a contributor touches and name the exact mistake — an unknown
or mistyped key, a duplicate, a blank value, a dropped {0} placeholder. They report, but never
fail, on an incomplete translation. Docs/TRANSLATING.md is the contributor guide.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The NuGet workflow already runs the tests, but only when a release is published — too late to
help anyone. CodeQL builds on pull requests but does not test.
This matters most for the community-contributed UI translations: the locale tests are what make
a translation pull request reviewable, reporting a mistyped key or a lost {0} placeholder by
name instead of leaving a maintainer to read two JSON files side by side. Running them only at
release time would have meant catching a broken translation after shipping it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
The analysis has been bilingual since the MVP, but the interface around it was English-only. A segmented EN/ES control in the toolbar now flips the whole UI instantly — no page reload — remembered per browser and following the browser's own language on a first visit.
Translations are data, not code
Because this is a project for the community, adding a language must not require knowing C#. Translations are plain JSON in
src/SignsOfAI.Web/wwwroot/i18n/listed in alocales.jsonmanifest — the same "it's just a data file" approach the rule packs already use. A new language is one file plus one manifest line, and the switch renders it with no code change.Docs/TRANSLATING.md.Verified by adding a deliberately 3%-complete French locale: it appeared in the switch on its own and everything untranslated fell back to English cleanly. (Removed before committing — a 3% translation shouldn't ship.)
The two-languages distinction
Findings deliberately stay in the language of the analyzed text, not the interface: advice about English prose is given in English even with a Spanish UI, because that's the language it describes. This looks like a bug the first time you see it and is intentional.
Guarding contributions
Six locale tests name the exact mistake — an unknown or mistyped key, a duplicate, a blank value, a dropped
{0}placeholder — so a translation PR is reviewable on evidence rather than by reading two JSON files side by side. They report, but never fail, on an incomplete translation. Verified by mutation: each guard was confirmed to fire against a deliberately broken locale file.The second commit adds a
CIworkflow so those tests actually run on pull requests; previously they ran only when a release was published.Checks
dotnet buildclean,dotnet test81 passed (75 before).localhostare unrelated to this change.🤖 Generated with Claude Code