manueljpconde takes mikeEU multilingual

The European fork now speaks five languages, with English as the fallback at every layer.

i18ninfrastructure

manueljpconde has wired end-to-end localization into mikeEU for English, Portuguese, Spanish, French, and German - covering the app shell, sign-in pages, sidebar, and common labels. Rather than reach for an off-the-shelf translation library, the team wrote a thin custom runtime: the server picks a language from a cookie or browser preference on first load, users can switch on the fly without a reload, and a signed-in user's choice follows them across devices via their profile.

Language preference is now a first-class field on the user profile, with the same five-language allowlist enforced in the database, the backend, and the frontend so the three layers can't drift. Scope is deliberately tight for v1 - backend-emitted error messages, transactional emails, and a final hardcoded-string sweep are flagged as explicit follow-ups, along with a translator-facing import/export workflow.

So what Worth a look for anyone eyeing Mike for a multi-country practice or considering whether a non-English-first deployment is realistic today.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

2 commits from manueljpconde/mikeEU, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
346b8197 feat: add localization support for en/pt/es/fr/de (#4) Manuel Conde 2026-05-10 ↗ GitHub
commit body
Adds i18n infrastructure (thin custom + native Intl, no library) covering
auth pages, sidebar nav, language switcher, and common labels across the
five supported locales. English is canonical fallback at every layer.

- Schema: user_profiles.locale text column with named CHECK constraint
- Backend: PATCH /user/profile accepts/persists locale with allowlist validation
- Frontend: server-side locale resolution (cookie -> Accept-Language -> en)
  in root layout; client I18nProvider for runtime switching; ProfileLocaleSync
  applies authenticated profile.locale one-way
- Cookie 'mike_locale' (non-httpOnly, Path=/, Max-Age=1y, SameSite=Lax)
- Catalog validator with structural + placeholder + plural-shape checks
- 51 automated tests (46 frontend + 5 backend) on pure logic; React surface
  covered manually
- Coupled allowlist triple flagged: schema CHECK / backend SUPPORTED_LOCALES
  / frontend SupportedLocale must move together

Spec:  https://github.com/manueljpconde/mikeEU/issues/4#issuecomment-4414976968
Plan:  https://github.com/manueljpconde/mikeEU/issues/4#issuecomment-4414987693
GO:    https://github.com/manueljpconde/mikeEU/issues/4#issuecomment-4415157201

Closes #4
cb6b9a2f fix(i18n): four review findings on PR #10 Manuel Conde 2026-05-10 ↗ GitHub
commit body
1. npm test scripts: replace quoted-glob args (which tsx received literally
   and didn't expand on bash 3.2) with a Node-based test discovery script
   per repo. Both `npm test --prefix frontend` and `npm test --prefix
   backend` now run the suites correctly.

2. Validator now rejects duplicate top-level JSON keys via a state-machine
   raw-text scan (findDuplicateTopLevelKeys), restoring the contract
   promised in spec rule 4. JSON.parse silently dedupes; this catches
   editor mistakes before runtime sees the deduped catalog.

3. Signup persists the active i18n locale alongside name/organisation
   so a guest who selected pt/es/fr/de doesn't get snapped back to en
   when ProfileLocaleSync applies the (default 'en') profile after
   signup.

4. Client setLocale now syncs document.documentElement.lang via useEffect
   on locale change. SSR sets it once; the effect keeps it in sync after
   user-driven switches.

Tests: frontend 55/55 (added 9 in findDuplicateTopLevelKeys.test.ts),
backend 34/34. Both `npm test` and `npm run lint:catalogs` runnable
without manual glob expansion.

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-249.md from inside the repo you want the changes in.

⬇ Download capture-thread-249.md