feat(i18n): add Italian (it) locale - #785
Open
SandroHub013 wants to merge 1 commit into
Open
Conversation
Adds the Italian translation of the shared locale files, following the community-contribution path described in 666ghj#428: a new locales/it.json plus an entry in locales/languages.json. No loader change is needed, since both frontend/src/i18n/index.js and backend/app/utils/locale.py discover locale files automatically. All 631 keys are translated. Placeholders, technical identifiers, API paths, and strings that must not be translated (MiroFish, GraphRAG, ReportAgent, the version and engine badges) are preserved verbatim. The locale-specific typography in Home.vue, Step4Report.vue and Step5Interaction.vue was keyed to html[lang=en] alone. Without extending those selectors Italian falls back to the CJK defaults (JetBrains Mono at 72px with -2px letter-spacing), which clips the hero title and pushes the upload panel below the fold. Italian is added alongside English as a selector list; no declaration inside those rules was changed.
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.
Summary
Adds Italian (
it) as a UI language, following the community-contribution path described in #428 ("7 languages pre-registered for community contribution; contributors only need to add a JSON file").Italian was not among the pre-registered codes, so this adds both halves that the loaders need:
locales/it.json— new, all 631 keys translatedlocales/languages.json— one entry:"it": { "label": "Italiano", "llmInstruction": "Per favore, rispondi in italiano." }Both are required:
frontend/src/i18n/index.js:11only registers a locale whose file and registry entry exist, whilebackend/app/utils/locale.py:31only accepts anAccept-Languagevalue that is present in the loaded translations.Because
get_language_instruction()feeds the LLM prompts inreport_agent.py,ontology_generator.py,simulation_config_generator.pyandoasis_profile_generator.py, this also makes generated reports and simulated personas respond in Italian, not just the UI chrome.Why this touches three
.vuefilesThe locale-specific typography is keyed to
html[lang="en"]alone. With only the JSON files added, Italian silently inherits the CJK defaults. Measured on the home page at 1440px:lang="en"lang="it"beforelang="it"after.main-title-1px-2px-1px.hero-desc-apple-system-apple-system.workflow-list .step-desc.main-titleheightThe practical effect is that the hero title wrapped to three oversized monospace lines and pushed the Reality Seed upload panel below the fold.
The fix is deliberately minimal: each
html[lang="en"]rule inHome.vue(11 rules),Step4Report.vueandStep5Interaction.vue(1 each) becomes a two-selector listhtml[lang="en"], html[lang="it"]. No declaration inside any rule body was changed — only selectors, plus the two comments that now describe more than English.I kept this explicit rather than generalising to something like
html:not([lang="zh"]), to stay in scope. Happy to send that generalisation as a separate PR if you'd prefer it, since it would let the next Latin-script locale be a pure JSON contribution again — which is what #428 promised.Translation conventions
en.json: same keys, same order, same nesting,main.stepNamesstill a 5-element array{placeholder}preserved verbatim — 230 keys contain oneMiroFish,GraphRAG,ReportAgent,OASIS,Zep, API paths, env var names,simulationId/project_ididentifiers,/ v0.1-Preview,Engine: MiroFish-V1.0,$5/sim>_,//,01 /prefixes, box-drawing characters in log lines, trailing ellipsesstep4.expandAll/step4.expandAllEntitiesdiffer ("tutti" vs "tutte") because Italian requires gender agreement and entità is feminine.Verification
No CI runs on pull requests in this repo, so I verified locally.
Backend — loaded
backend/app/utils/locale.pydirectly and asserted:it.jsonis discovered anditis declaredset_locale('it')propagates through the thread-localt()— none returns the raw key, none silently falls back to another localeget_language_instruction()returns the Italian instructionFrontend — ran the dev server and exercised the real UI:
document.documentElement.langbecomesit, on switch and on reloadRegression — Chinese and English are untouched:
t('common.confirm')still returns 确认 / Confirm with their original LLM instructions, andlang="zh"still computes to 72px JetBrains Mono-2px, identical to before this change.vite buildcould not be used as a check here becauseesbuildfails on a temp-file permission error in my Windows environment, unrelated to this change; the dev server and the module graph build fine.Notes
Two things I noticed while working on this but deliberately left out of scope:
meta.titleandmeta.descriptionexist in every locale file but are never read —frontend/index.htmlhardcodes the Chinese<title>and description, so the browser tab stays Chinese in every language.backend/app/utils/locale.py:31matchesAccept-Languageby exact string, so a real browser value such asit-IT,it;q=0.9falls back to Chinese. It works today only because the axios interceptor always sends a bare code.Happy to open issues or follow-up PRs for either if useful.
Suggested label: enhancement (I don't have permission to set labels on this repo).