feat(i18n): adopt next-intl + migrate every visible string (#146) #153
No reviewers
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol!153
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "146-i18n"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #146.
Summary
next-intlwith single-locale-per-request resolution(
?locale=→carol_localecookie →Accept-Language→DEFAULT_LOCALE) — logic inlib/i18n/locales.ts, wired throughlib/i18n/request.ts.messages/en.jsonis the source-of-truth catalog. Sibling localesmay be partial — missing keys silently fall back to English per-key.
A smoke
messages/es.jsonships coveringhome,nav, andlogin.app/(app)/,/login,/register, thehome page, and shared components routes through
useTranslations()(client) or
getTranslations()(server).locale-picker-server.tsx) rendersnullwhenSUPPORTED_LOCALEShas one entry; client island writesthe cookie via a server action and
revalidatePath("/", "layout")./offlinestays English-only(force-static can't read cookies); zod schema messages deferred to
a follow-up.
DEFAULT_LOCALE+SUPPORTED_LOCALESadded to README Operationstable. CLAUDE.md Conventions gains the no-hardcoded-strings rule.
ADR-0025 captures the library choice, resolution chain, and partial-
catalog policy.
Test plan
npx tsc --noEmitcleannpm run lintcleannpx vitest run— 440 passed / 91 skipped, including 19 newtests in
tests/i18n/resolve.test.tscovering the resolutionchain (fallback, header negotiation, region-strip, env parsing)
npm run buildsucceeds/?locale=eswithSUPPORTED_LOCALES=en,es→ home pagerenders Spanish strings, falls back to English for unmigrated
surfaces
carol_localecookie and the new locale persists across pagesAccept-Language: es,en;q=0.5with no cookie → home rendersSpanish
Trivy (container image)
Threshold:
high· Total findings: 121 · At/above threshold: 16.27.0, 7.28.0, 8.5.0📊 Test coverage
Patch coverage: 37.4% (49/131 added lines) ⚠️ (soft target ≥ 80%)
Overall (
app/,lib/,db/, excluding UI per ADR-0019):Changed files in this PR (source only — tests excluded):
app/(app)/components/placeholder.tsxapp/(app)/components/top-nav.tsxlib/dto/auth.tslib/i18n/locales.tslib/i18n/request.tslib/i18n/set-locale-action.tsSoft thresholds per ADR-0019. Coverage is informational and does not block merge.