Skip to content

feat: complete Marathi, Tamil and Telugu support and persist the language choice - #1665

Open
Anijesh wants to merge 2 commits into
viru0909-dev:mainfrom
Anijesh:feat/1629-multilingual-marathi-tamil-telugu
Open

feat: complete Marathi, Tamil and Telugu support and persist the language choice#1665
Anijesh wants to merge 2 commits into
viru0909-dev:mainfrom
Anijesh:feat/1629-multilingual-marathi-tamil-telugu

Conversation

@Anijesh

@Anijesh Anijesh commented Jul 30, 2026

Copy link
Copy Markdown

Description

Locale directories for mr, ta and te already existed on main, so I started by auditing what actually worked. The bundles were largely written, but the feature was not finished — and two of the failures were invisible at runtime.

This PR closes the remaining gaps across all five points in the issue.

Issue Resolved

Closes #1629

What I found first

# Issue asks for State on main
1 Locale files for mr, ta, te Present, but ta/forms.json and te/forms.json were zero-byte files, and 20 FAQ keys were missing from every non-English bundle
2 Translate litigant flows Largely done; 25 keys short overall
3 Language selector in navbar Present in both headers, but offered 5 languages with no locale files at all
4 Persist preference to profile Entirely absent — no column, no endpoint, localStorage only
5 Vakil Friend follows the preference Absent — its own dropdown hardcoded English regardless of the UI language

Changes Made

1 & 2 — Locale bundles

ta/forms.json and te/forms.json were empty files. i18next could not parse them, so the namespace failed to load and Tamil and Telugu users silently got English — no console error, no visible failure.

Also translated the 20 landing-page faq.* keys (missing from all four non-English bundles), vakilFriend.connectError, and the remaining Hindi-only gaps in litigant.common and constitution. Every bundle now matches English key for key.

3 — Language switcher

The landing header and the dashboard header each carried their own hardcoded list, and they disagreed: the dashboard offered gu, kn, bn, ml and pa, none of which have locale files. Picking Kannada left you in English with no explanation.

  • New src/config/languages.js is the single source of truth for both headers, i18n.js and Vakil Friend.
  • The five translated languages are selectable; the other five appear under a "Coming soon" group and cannot be chosen. I kept them visible rather than deleting them, since listing them was clearly deliberate — this just stops them silently failing.
  • supportedLngs is now derived from the config, so i18next no longer requests bundles that 404.

On flags: the issue asks for "flag + language name". I kept the EN / HI / MR / TA / TE code badge the landing header already used, because five identical 🇮🇳 flags would distinguish nothing and it matches the existing design. Trivial to switch if you'd rather have literal flags.

4 — Language preference on the profile

  • V54__add_preferred_language_to_ny_user.sql adds a nullable preferred_language. Null means "never chose one", so existing users keep browser detection.
  • GET and PUT /profile/language on the existing authenticated /profile controller, acting on the signed-in user via Authentication rather than a path userId.
  • Validation lives in the DTO and is pinned to the languages that actually ship.
  • The frontend saves on every switch and re-applies at login. Every call is best-effort — a guest session or an offline device must never stop someone changing language locally.

5 — Vakil Friend

Its language dropdown always started at English, disconnected from the interface language. It now seeds from the UI language and follows later switches.

The assistant still lists all ten languages, and deliberately so: its replies are machine-translated by Bhashini per request rather than read from a locale bundle, so it can converse in languages the interface itself isn't translated into yet. That is a real distinction, and the config models it as two separate capabilities.

Also replaced the duplicated language list and the hand-rolled 'xx' + '-IN' speech-locale logic with the shared config.

Tests

src/__tests__/localeCompleteness.test.js holds every shipped language to English key coverage and rejects empty or malformed bundles. I verified it fails when te/forms.json is emptied — it catches exactly the bug that shipped here unnoticed, so the next bundle to drift fails CI instead of quietly degrading for users.

How to Test

  1. Sign in, open the profile menu, pick मराठी — the dashboard switches immediately.
  2. Sign out, sign in from a different browser or incognito → it comes back in Marathi. Previously it reset to English.
  3. Open Vakil Friend → the chat language is already Marathi rather than English.
  4. Switch to தமிழ் and visit a page using the forms namespace — it renders Tamil. On main that bundle fails to parse.
  5. Scroll to the landing FAQ in each language — previously English in all four.
  6. Open the profile menu and note Gujarati/Kannada/Bengali/Malayalam/Punjabi under "Coming soon", no longer selectable.
  7. Reject an unsupported code directly:
    curl -i -X PUT http://localhost:8080/profile/language \
      -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
      -d '{"language":"gu"}'

Testing Completed

  • npx vitest run161 passed, 1 failure in CaseDetailPage.test.jsx that also fails on a clean main (unrelated)
  • 113 of those are new: 101 locale-completeness, 12 language-config
  • mvn test -Dtest=ProfileServiceLanguageTest16 passed
  • Full backend suite compared against a clean main: 27 errors before, 27 after — identical set, all @SpringBootTest context loads needing a database
  • npm run build — see below

Two pre-existing syntax errors fixed here

Both are in files this PR already edits, and both stopped the frontend compiling:

  1. litigant/VakilFriendPage.jsx — the AI Summary block lost its paragraph body and closing tag in f7bdcd1, leaving <p> followed directly by </div>. (Same two lines as feat: add frontend input sanitization and length validation for Vakil Friend AI chat #1663; identical change, so the two branches merge cleanly.)
  2. landing/Header.jsxcurrentPathWithHash, isActive and baseStyle were each declared twice.

Still blocking npm run build, left out of scope

src/pages/judge/RedactionReviewPage.jsx and src/pages/lawyer/SemanticSearchPage.jsx both do import { api } from '../../services/api', but that module only has a default export. Changing both to import api from '../../services/api' is the whole fix — with those two lines patched locally, the full production build succeeds, which is how I verified this PR end to end. They have nothing to do with i18n so I left them out; happy to include them or open a separate PR.

Separately, mvn needs com.networknt:json-schema-validator added to pom.xml to compile at all (detailed in #1664), and db/migration has duplicate V51 and V52 versions, which Flyway rejects. Neither is touched here.

Breaking Changes

None. The only user-visible removal is that five languages which previously appeared selectable but silently rendered English are now labelled "Coming soon" — they never worked.

Follow-up worth a separate issue

src/contexts/LanguageContext.jsx is a second, parallel translation system with its own hardcoded English/Hindi dictionary and an en ⇄ hi toggle. The police dashboard pages use it, so those pages can never show Marathi, Tamil or Telugu no matter what this PR does. Migrating them onto i18next is a self-contained follow-up.

… choice

Locale directories for mr, ta and te already existed, but the feature was
not finished: two bundles were unusable, the switcher offered languages
that had no translations at all, the choice lived only in localStorage,
and Vakil Friend ignored it entirely.

Locale bundles:
- ta/forms.json and te/forms.json were zero-byte files. i18next could not
  parse them, so the namespace failed to load and Tamil and Telugu users
  silently fell back to English with no error surfaced anywhere
- Translate the 20 landing-page FAQ keys, absent from all four non-English
  bundles, plus vakilFriend.connectError and the remaining Hindi gaps
- Every bundle now matches English key for key

Language switcher:
- Add src/config/languages.js as the single source of truth; the landing
  header and dashboard header each carried their own divergent list
- The dashboard header offered gu, kn, bn, ml and pa, none of which have
  locale files, so choosing one silently left the user in English. They are
  now shown under "Coming soon" and cannot be selected
- Narrow i18next supportedLngs to the languages that actually ship

Language preference:
- Add preferred_language to ny_user (V54) with GET and PUT /profile/language
  on the authenticated profile endpoint
- Persist on every switch and re-apply at login, so the choice follows the
  user to a shared computer or a new phone instead of dying with the browser

Vakil Friend:
- Seed the chat language from the interface language rather than hardcoding
  English, and follow later switches. Replies are machine-translated by
  Bhashini per request, so the assistant still covers all ten languages
- Replace the duplicated language list and hand-rolled 'xx' + '-IN' speech
  locale logic with the shared config

Tests:
- localeCompleteness.test.js holds every shipped language to English key
  coverage and rejects empty or malformed bundles. Verified it fails when
  te/forms.json is emptied, which is the bug that shipped unnoticed
- 12 cases for the language config, 16 for the backend preference

Also restores the AI Summary paragraph in VakilFriendPage and removes a
duplicated block in landing/Header.jsx; both files are edited here and both
had syntax errors that stopped the frontend compiling.

Closes viru0909-dev#1629
@Anijesh
Anijesh requested a review from viru0909-dev as a code owner July 30, 2026 09:59
@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the CodeBlooded's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

Copy link
Copy Markdown
Contributor

Hi @Anijesh, thanks for contributing to Nyay Setu! 🎉

I have automatically:

  • 👤 Assigned this PR to you.
  • 🏷️ Applied the gssoc:approved label.

Our workflows will now analyze your changes to classify:

  • 📈 PR Difficulty: level:*
  • 🧩 PR Type: type:*
  • 🌟 PR Quality: quality:*

Tip

Ensure your PR description references the issue it resolves (e.g. Closes #123). This allows the bot to inherit any additional labels from that issue!

Happy coding! 🚀

WebMvcConfig.addPathPrefix puts every @RestController in the package behind
/api/v1, so ProfileController is served at /api/v1/profile, not /profile.
The language calls omitted the prefix and would have 404'd. Both callers
swallow errors by design, so the switcher would have kept working locally
while the preference silently never persisted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Add multilingual support for Marathi, Tamil, and Telugu in addition to existing Hindi

1 participant