Skip to content

feat(web): set up i18n foundation with a language switcher#311

Closed
cavidelizade wants to merge 1 commit into
Devlaner:mainfrom
cavidelizade:feat/i18n-setup
Closed

feat(web): set up i18n foundation with a language switcher#311
cavidelizade wants to merge 1 commit into
Devlaner:mainfrom
cavidelizade:feat/i18n-setup

Conversation

@cavidelizade

@cavidelizade cavidelizade commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Feature summary

Sets up internationalization for the UI: a react-i18next foundation, English + Spanish bundles, and a language switcher, with the sign-in page converted as the first translated surface.

Linked issues / discussion

Closes #32

User-facing behavior

The sign-in page now renders from translation keys and shows a Language selector (English / Español). Choosing a language re-renders the page in that language immediately and persists the choice to localStorage, so it survives reloads. The default is English.

What changed

UI (apps/web/)

  • Added i18next + react-i18next.
  • src/i18n/index.ts: single i18next init, resources for en and es split into common and auth namespaces, initial language read from localStorage (devlane.language, default en), plus setLanguage() and SUPPORTED_LANGUAGES.
  • src/i18n/locales/{en,es}/{common,auth}.json: the string bundles.
  • main.tsx: imports ./i18n to initialize before render.
  • LoginPage.tsx: strings replaced with t('auth:…') keys.
  • LanguageSwitcher.tsx: compact selector, mounted on the sign-in page.
  • tsconfig.app.json: resolveJsonModule for importing the JSON bundles.

API / Database

  • None.

Why this design

react-i18next is the de-facto standard for React i18n and integrates cleanly with hooks. A single initialized instance keeps useTranslation() working app-wide without threading a provider. Namespaces (common, auth) keep bundles small and lazy-migratable. The sign-in page is a good first surface: it's public (verifiable without auth), self-contained, and exercises the whole path (keys, switcher, persistence). This is deliberately a foundation — the rest of the app can be migrated to keys incrementally without further plumbing.

Test plan

  • npm run validate (typecheck + lint + prettier) green
  • Manual end-to-end (Playwright): sign-in renders from keys in English; switching to Español updates the heading/labels/buttons live ("Comienza con Devlane", "Continuar con el correo", "Idioma"); the choice persists across a reload (localStorage = es)
  • Tested at narrow viewport

Out of scope (follow-ups)

  • Migrating the rest of the app's surfaces to translation keys
  • Additional languages / translator workflow
  • Persisting language preference to the user's account (server-side)

AI assistance

  • AI tools were used — tool(s): Claude Code (Claude Opus 4.8) — and AI-assisted commits include a Co-Authored-By: trailer

Checklist

  • PR title follows Conventional Commits and is ≤ 100 chars
  • Acceptance criteria from the linked issue are met (i18n set up + working language switch)

Summary by CodeRabbit

  • New Features
    • Added English and Spanish language support for the authentication experience.
    • Added a language selector to switch between English and Spanish.
    • The selected language is remembered for future visits.
    • Localized sign-in, sign-up, password, email-code, and social login text.
  • Improvements
    • Authentication language now loads automatically when the app starts.
    • Added localized language names and labels for the selector.

Introduce internationalization so the UI can be translated. Adds i18next +
react-i18next, initialized once from a localStorage-backed language preference
(default English), with English and Spanish resource bundles split into
"common" and "auth" namespaces.

As the first converted surface, the sign-in page now pulls its strings from
translation keys, and a compact LanguageSwitcher (English / Español) lets you
change the UI language; the choice persists across reloads. The rest of the app
can be migrated to translation keys incrementally on top of this.

Closes Devlaner#32

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cavidelizade cavidelizade requested a review from a team as a code owner July 13, 2026 14:15
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The web app adds English and Spanish i18n resources, persists language selection, introduces a language switcher, initializes i18n at startup, and localizes the login page.

Changes

Web internationalization

Layer / File(s) Summary
i18n configuration and resources
apps/web/package.json, apps/web/tsconfig.app.json, apps/web/src/i18n/...
i18next is configured with English and Spanish authentication and common resources, persisted language selection, and JSON module imports.
Localized login flow
apps/web/src/pages/LoginPage.tsx
Authentication labels, buttons, statuses, accessibility text, and flow-specific messages use the auth translation namespace.
Language selector and startup wiring
apps/web/src/components/LanguageSwitcher.tsx, apps/web/src/main.tsx
A supported-language selector applies language changes, and i18n initialization runs before the application starts.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant LanguageSwitcher
  participant i18n
  participant LoginPage
  User->>LanguageSwitcher: select language
  LanguageSwitcher->>i18n: setLanguage(code)
  i18n-->>LoginPage: resolve translated strings
  LoginPage-->>User: render localized login UI
Loading

Poem

A bunny hops through English and Español,
With tiny translations tucked in his rolls.
The login fields sing, the buttons glow,
And saved-up languages help them know.
“Hop to a new tongue!” the rabbit cries.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding an i18n foundation and language switcher for the web app.
Linked Issues check ✅ Passed The PR implements issue #32 by adding i18n setup, English/Spanish bundles, language persistence, and the multilingual sign-in UI.
Out of Scope Changes check ✅ Passed The changes stay within the i18n scope and related login-page localization, with no unrelated feature work evident.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/web/src/i18n/index.ts (1)

13-18: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider deriving language labels from a single source.

SUPPORTED_LANGUAGES hardcodes labels ('English', 'Español') that also exist in common.json under languageName. Adding a third language requires updating both places. If SUPPORTED_LANGUAGES is primarily used for the LanguageCode type derivation and the switcher uses the t('common:languageName.es') path, consider keeping only code in the array and sourcing labels from the translation bundles.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/i18n/index.ts` around lines 13 - 18, Update SUPPORTED_LANGUAGES
to contain only language codes, removing the duplicated label values, while
preserving LanguageCode derivation from the array. Ensure language-switcher
display labels continue to come from the translation bundles via the existing
common:languageName translation paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/web/src/i18n/index.ts`:
- Around line 13-18: Update SUPPORTED_LANGUAGES to contain only language codes,
removing the duplicated label values, while preserving LanguageCode derivation
from the array. Ensure language-switcher display labels continue to come from
the translation bundles via the existing common:languageName translation paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 10318c32-57ba-49a2-8cf4-cfcde15977cb

📥 Commits

Reviewing files that changed from the base of the PR and between dc28bb0 and 4822e94.

⛔ Files ignored due to path filters (1)
  • apps/web/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • apps/web/package.json
  • apps/web/src/components/LanguageSwitcher.tsx
  • apps/web/src/i18n/index.ts
  • apps/web/src/i18n/locales/en/auth.json
  • apps/web/src/i18n/locales/en/common.json
  • apps/web/src/i18n/locales/es/auth.json
  • apps/web/src/i18n/locales/es/common.json
  • apps/web/src/main.tsx
  • apps/web/src/pages/LoginPage.tsx
  • apps/web/tsconfig.app.json

@cavidelizade

Copy link
Copy Markdown
Contributor Author

@martian56 this one's green with no CodeRabbit comments — the i18n foundation (react-i18next + language switcher, sign-in page translated en/es). Good to merge when you get a chance.

@martian56

Copy link
Copy Markdown
Member

@cavidelizade I added some description to the #32, closing this PR, feel free to open a new one

@martian56 martian56 closed this Jul 13, 2026
@cavidelizade cavidelizade deleted the feat/i18n-setup branch July 13, 2026 15:46
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.

Setup I18n for multilingual UI

2 participants