Skip to content

feat(wallet): add react-i18next with English + Spanish translations - #553

Open
ibochielizabeth-spec wants to merge 1 commit into
Miracle656:mainfrom
ibochielizabeth-spec:feat/wallet-i18n
Open

feat(wallet): add react-i18next with English + Spanish translations#553
ibochielizabeth-spec wants to merge 1 commit into
Miracle656:mainfrom
ibochielizabeth-spec:feat/wallet-i18n

Conversation

@ibochielizabeth-spec

Copy link
Copy Markdown
Contributor

Summary

  • Wires up react-i18next + i18next-http-backend + i18next-browser-languagedetector: lib/i18n.ts (init, browser-only guarded so it doesn't crash SSR) and lib/i18nConfig.ts (pure constants: supported languages, namespaces, storage key), initialised client-side via app/I18nInit.tsx (mounted in app/layout.tsx), which also keeps <html lang> in sync.
  • Translation JSON lazy-loaded from public/locales/{lng}/{ns}.json, namespaces common, dashboard, send, receive, errors, English + Spanish for each.
  • Fully translates: the dashboard header/title/subtitle + "signing key not found" banner, the entire send flow (app/send/page.tsx), and the entire receive flow (app/receive/page.tsx, including AddressCard).
  • Adds <LanguageSwitcher /> (components/LanguageSwitcher.tsx) to Settings' nav bar, next to the existing theme toggle.
  • Manual language switch persists to localStorage under veil_language (same convention as the existing veil_theme key); browser language is auto-detected via i18next-browser-languagedetector on first load when nothing is stored yet.
  • Adds lib/__tests__/i18nLocales.test.ts: parses every locale JSON file and asserts each non-English locale has exactly the same (flattened, nested-aware) key set as English, so a missing/renamed Spanish key fails CI instead of silently rendering a blank string.
  • Documents all of this in the wallet README, including which pages are not yet covered.

Scope note: the issue's "Key files" list is app/**/*.tsx and components/**/*.tsx (the whole app). Doing a full sweep of all 41 wallet pages/components in one pass, in an environment where I can't run tsc/next build/the test suite to catch mistakes, felt riskier than it was worth — a wide shallow pass risks shipping broken JSX with no way to verify it here. Instead I fully wired the infrastructure end-to-end (detection, persistence, lazy loading, CI-checked locale parity) and fully translated the three flows the issue explicitly calls out as the minimum bar ("Spanish covers the main flows: dashboard + send/receive"), plus the settings language switcher. The remaining pages (swap, agent, settings sub-pages, contacts, multisig, buy/withdraw, recover, vault, etc.) are still English-only literals; extending them is a mechanical follow-up using the same pattern (add keys to a namespace file in both languages, swap the literal for t('key')) and is called out explicitly in the README so it isn't lost track of.

closes #170

Test plan

  • Added lib/__tests__/i18nLocales.test.ts (locale JSON validity + en/es key-parity check).
  • Manually traced the translated pages: every literal user-facing string in dashboard (header only), send, and receive now goes through t(); verified via grep for stray capitalized JSX text that no un-translated strings remain in send/page.tsx and receive/page.tsx.
  • npm install && npm test && npm run typecheck / manual browser check (detection, switch, persistence, reload) — not run: this sandbox has no Node.js installed, so I could not execute the toolchain or verify in a real browser. Please run these before merging.

Wires up react-i18next (browser language auto-detection, manual switch
persisted to localStorage under veil_language, lazy-loaded JSON from
public/locales/{lng}/{ns}.json) and fully translates the dashboard
header, send flow, and receive flow into English + Spanish, plus a
language switcher in Settings.

A locale-consistency test (i18nLocales.test.ts) fails CI if a Spanish
translation file drifts from English's key set. Remaining pages (swap,
agent, settings sub-pages, contacts, multisig, etc.) are still
English-only literals — noted as follow-up work in the wallet README.
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

@ibochielizabeth-spec is attempting to deploy a commit to the miracle656's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@ibochielizabeth-spec Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Miracle656

Copy link
Copy Markdown
Owner

Apologies for the month — and unfortunately the delay hurt this PR more than most.

It no longer merges. Conflicts on four files:

frontend/wallet/app/dashboard/page.tsx
frontend/wallet/app/receive/page.tsx
frontend/wallet/app/send/page.tsx
frontend/wallet/app/settings/page.tsx

Every one of those has been redesigned in the last two days — dashboard (#656, #664), send (#673), receive (#669), settings (#664).

Why that is worse for an i18n PR specifically: i18n wraps every user-facing string. A redesign rewrites them. So it is not that the diff moved — it is that most of the strings this PR extracted no longer exist to be extracted. A mechanical rebase would mostly produce translation keys pointing at deleted copy.

What I would salvage

The setup is still good and does not conflict:

  • frontend/wallet/app/I18nInit.tsx
  • The layout.tsx wiring
  • The dependency and config
  • The English and Spanish resource files as a starting corpus

The per-screen string extraction is what needs redoing against current main.

If you are up for it, the highest-value version now would be: land the i18n scaffolding on its own, with one screen converted as proof, and let the rest follow screen by screen. That also stops this happening again — a big-bang extraction is permanently one redesign away from being stale, whereas incremental conversion is not.

Worth knowing

frontend/website already runs EN/ES through messages/en.json / es.json with a Messages = typeof en type. Matching that shape in the wallet would mean one mental model across both, and the Spanish already written there is a reference for tone.

Entirely fair if you would rather not carry this after the wait. Not closing it. If you would prefer it re-scoped as a fresh issue with the scaffolding-first approach written down, say the word and I will do that instead.

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.

Add internationalization (react-i18next)

2 participants