Skip to content

i18n: add Hindi (hi) translations across all namespaces - #242

Open
bikash1376 wants to merge 2 commits into
AtomicBot-ai:mainfrom
bikash1376:feature/hindi-locale
Open

i18n: add Hindi (hi) translations across all namespaces#242
bikash1376 wants to merge 2 commits into
AtomicBot-ai:mainfrom
bikash1376:feature/hindi-locale

Conversation

@bikash1376

Copy link
Copy Markdown

Adds web-app/src/locales/hi/ (17 namespace files, key-parity verified against en/) and registers hi in the language switcher and Language type.

Describe Your Changes

Adds Hindi as a new language option. All 17 locale namespaces under web-app/src/locales/hi/ are translated, and hi is registered in the language switcher and the Language type.

Went with a spoken/developer friendly register instead of formal textbook Hindi - kept common English terms (GPU, API, save, delete, etc.) as-is since that's how most Hindi-speaking devs actually talk, rather than forcing pure Hindi words for everything.

Verification

  • All 17 files are valid JSON, checked against en/ for matching keys (nothing missing or extra)
  • Checked every {{placeholder}} and matches the English source exactly, so nothing breaks at runtime
  • Double checked the llamacpp DFlash strings in settings.json against where they're actually used in the code, since that block is easy to mix up with the separate MLX dflash/mtp/eagle3 strings
  • yarn lint passes clean
  • Tested it running locally.

@bikash1376
bikash1376 requested a review from Vect0rM as a code owner August 18, 2026 14:27

Vect0rM commented Aug 20, 2026

Copy link
Copy Markdown
Member

Thank you for this, @bikash1376 — 1,566 lines across all seventeen namespaces is a serious piece of work, and the quality shows in the details. Hindi is a language we've had requests for.

I checked it mechanically rather than by eye, since that's where locale PRs usually go wrong:

  • All 17 namespaces present, matching en file-for-file.
  • Zero placeholder mismatches. Every {{count}}, {{provider}}, {{modelId}} survives the translation with the same set per key — this is the single most common way a locale PR breaks at runtime, and it's clean.
  • Zero extra keys (nothing renamed or invented).
  • The 32 strings identical to English are all correct to leave aloneGitHub, Discord, CPU, VRAM, Vulkan, ANN (sqlite-vec), Shift + Enter, the path placeholders. A machine-translated pass would have mangled those.
  • tsc -b exit 0, eslint clean, prettier --check src/locales/hi/*.json clean, merges cleanly.

The wiring is right too: i18n/setup.ts globs ../locales/**/*.json, so the directory is picked up automatically, and you correctly updated both LANGUAGES in LanguageSwitcher.tsx and the Language union in types/app.d.ts — the second one is easy to miss.

One thing before merge: main moved under you

6b535b6 ("enhance onboarding and download management for low-spec devices") landed on 19 Aug, a day after you opened this, and added 20 keys that hi doesn't have yet:

  • setup.json → the whole cloudStep block (17 keys): trigger, keyTitle, keyLabel, keyDescription, keyPlaceholder, keyProtected, keyOnly, showKey, hideKey, saveKey, saved, saveFailed, empty, galleryTitle, galleryDescription, modelCountOne, modelCountOther
  • chat.json: selectModelToChat
  • settings.json: general.preloadModelOnStartup, general.preloadModelOnStartupDesc

Nothing breaks without them — translate() falls back to en — but a Hindi user would hit the onboarding cloud step in English, which is exactly the moment you don't want a fallback. Could you rebase on main and add those?

One note on modelCountOne / modelCountOther: they're a plural pair, and Hindi's plural rules differ from English's, so please translate them as a pair rather than deriving one from the other.

Once those land I'll merge. Genuinely nice work — this is the cleanest locale contribution we've had 🙏


Generated by Claude Code

Adds web-app/src/locales/hi/ (17 namespace files, key-parity verified
against en/) and registers hi in the language switcher and Language type.

Rebased onto main @ v2.0.23; translates the 20 keys main added since this
PR opened (setup.json cloudStep, chat.selectModelToChat,
settings.general.preloadModelOnStartup*) and drops the stale
dialogs.editMessage.title that main replaced with top-level editMessage.
@bikash1376
bikash1376 force-pushed the feature/hindi-locale branch from 5616dde to d58b8b7 Compare August 21, 2026 18:41

Vect0rM commented Aug 22, 2026

Copy link
Copy Markdown
Member

Thanks for the rebase, @bikash1376 — everything from last round is closed, and you went further than I asked. Dropping the stale dialogs.editMessage.title that main had already flattened to a top-level editMessage wasn't in my list; you spotted it yourself and it now matches en and ru.

Verified on your branch (based on 9097a05, so it fast-forwards — no conflicts):

  • Key parity is exact. 1,331 keys across all 17 namespaces: 0 missing, 0 extra, 0 non-string values.
  • 0 placeholder mismatches — every {{count}}, {{provider}}, {{modelId}} carries through with the same set per key.
  • 0 markup divergence. I also compared HTML tags, backticked code, markdown links, embedded URLs and newlines between each en/hi pair — nothing dropped or malformed.
  • All 20 keys from last round are in: the full 17-key cloudStep block, chat.selectModelToChat, and both settings.general.preloadModelOnStartup*.
  • tsc -b — exit 0. yarn lint — 0 errors (13 react-refresh/exhaustive-deps warnings, all in files this PR doesn't touch, all present on main).
  • prettier --check src/locales/hi/*.json — all 17 clean.
  • Full vitest run — 194 files, 2029 passed, 11 skipped. Byte-identical to the main baseline (194 / 2029 / 11), so nothing is disturbed.
  • vite build — exit 0, and I grepped the output bundle: the cloudStep strings and the हिन्दी switcher label are really in there, so the import.meta.glob pickup works end to end.

modelCountOne / modelCountOther are right, too — मॉडल is invariant as a loanword, so the pair genuinely is 1 मॉडल / {{count}} मॉडल rather than one derived from the other.

One thing to fix, and it's a single word.

inspectFolder.prompt drops one of the five prohibitions

web-app/src/locales/hi/chat.json:95. English lists five forbidden operations; the Hindi lists four — replace is missing:

EN: Do not delete, overwrite, replace, rename, or modify any files or folders.
HI: …को डिलीट, ओवरराइट, रीनेम या मॉडिफाई न करें। → delete, overwrite, rename, modify

This one matters more than a normal string, because it isn't UI text — it's a prompt that goes straight to the model. AgentTaskSuggestions.tsx:48 does onSelect(t(task.promptKey)), so whatever this key resolves to is what an agent with filesystem access on the user's Desktop actually receives. A Hindi user gets a weaker constraint list than an English one.

The other locales that have this key keep all five — ru has не заменяй, ja has 置換. Adding रिप्लेस to the chain lines hi up with them:

"prompt": "मेरी डेस्कटॉप फ़ाइलों और फ़ोल्डर्स को व्यवस्थित करें। किसी भी फ़ाइल या फ़ोल्डर को डिलीट, ओवरराइट, रिप्लेस, रीनेम या मॉडिफाई न करें।"

I checked the rest of the locale for the same class of problem — every English string with three or more enumerated items, compared against its Hindi counterpart. Five others came up on a comma count (agentErrors.unsupportedTools, projects.filesDescription, codingAgentsDesc, attachments.subtitle, backendMismatch.cudaRuntimeHint) and all five are fine — they're just Hindi joining the final item with या instead of a serial comma. This is the only genuine omission.

Not yours — don't fix here

  • src/types/app.d.ts fails prettier --check on your branch, and fails identically on main. Pre-existing drift; reformatting it would bury your diff.
  • While confirming you'd updated both registration points (you had), I noticed the Language union is missing es, ja, pt-BR and ru — all four ship as locales and appear in LANGUAGES. The lng as Language cast at LanguageSwitcher.tsx:37 is what keeps it compiling. Long-standing, nothing to do with this PR; I'll open a separate issue.

Add रिप्लेस and I'll merge this. The register you chose was the right call — keeping GPU, API, सेव, डिलीट as-is reads the way Hindi-speaking developers actually write, and the DFlash block you double-checked is exactly the trap that catches people 🙏


Generated by Claude Code

The Hindi inspectFolder.prompt listed four of the five forbidden
operations from `en`, dropping "replace". This key is not UI text:
AgentTaskSuggestions.tsx passes t(task.promptKey) directly to an agent
with filesystem access, so Hindi users were sending a weaker constraint
list than English users. Adds रिप्लेस, matching `ru` (не заменяй) and
`ja` (置換).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FgJTbWwdyx4n9WXmz7nASD

Vect0rM commented Aug 25, 2026

Copy link
Copy Markdown
Member

Thanks for turning that around so quickly, @bikash1376 — the रिप्लेस fix is in and it's right. All five prohibitions are now present and the phrasing keeps the Hindi joining pattern (… रीनेम या मॉडिफाई) rather than forcing an English-style serial comma, which is what ru and ja do too. Your commit message explaining why that key isn't ordinary UI text is a better record of the reasoning than my comment was.

Re-verified on your branch merged onto current main (96a13ac):

  • Merges cleanly — no conflicts.
  • Key parity: 1,331 of 1,333. 0 extra, 0 non-string values. The two missing ones are new and aren't your fault — see below.
  • 0 placeholder mismatches, 0 markup divergences (HTML tags, backticked code, markdown links, embedded URLs, newline counts, all compared per en/hi pair).
  • tsc -b — exit 0. yarn lint — 0 errors (13 react-refresh/exhaustive-deps warnings, all pre-existing on main in files you don't touch). prettier --check on all 17 locale files plus app.d.ts and LanguageSwitcher.tsx — clean.
  • Full vitest run — 196 files, 2063 passed, 11 skipped. Byte-identical to the main baseline, so nothing is disturbed. (Higher than the 2029 I quoted last round because main has gained tests since, not because of anything here.)
  • vite build — exit 0, and I grepped the output: रिप्लेस and the हिन्दी switcher label are both really in the bundle, so the fix ships rather than just sitting in the JSON.

I also re-ran the enumeration audit that caught replace in the first place — every English string with three or more listed items, compared against its Hindi counterpart. Six still differ on a raw comma count and all six are the या join, not omissions; inspectFolder.prompt is now among them rather than genuinely short. That class of problem is closed.

One thing left, and it isn't yours

main moved under you again. #257 (96a13ac, landed 25 Aug) added two keys to common.json that hi doesn't have yet:

common.json → openInNewWindow        "Open in new window"
common.json → openInNewWindowFailed  "Couldn't open this chat in a new window"

All fourteen other locales got them in that commit; hi missed out only because it isn't on main yet. They're the thread context-menu item and its failure toast (ThreadList.tsx:274 and :189), so a Hindi user right-clicking a thread would see one English row in an otherwise Hindi menu.

Matching the register you've used elsewhere — विंडो for window, and the … नहीं हो सका/नहीं खुल सकी shape your other failure toasts use:

"openInNewWindow": "नई विंडो में खोलें",
"openInNewWindowFailed": "यह चैट नई विंडो में नहीं खुल सकी"

Take or change those as you see fit — you've been a better judge of the register than I am throughout this.

Rebase, add those two, and I'll merge. Apologies that main keeps moving out from under a PR that's been ready twice now; the locale is in good shape and this is the last mechanical thing standing between it and merge 🙏


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants