LegalLayout LanguageSwitcher Mount — Language Toggle Exposed on /privacy, /terms

Date
ImpactMedium

Decisions

D1: Suspense + LanguageSwitcher Mounted in LegalLayout Nav (Wave A)

  • Context: In Sprint 129, LanguageSwitcher was mounted at 4 locations with Suspense pattern (AppLayout L384/L464, AuthShell L43, LandingContent L80). In Sprint 131, TopNav was deleted → AppLayout unified. However, LegalLayout (/privacy, /terms) is a separate layout with no LanguageSwitcher mounted — language switching unavailable when visiting legal pages.
  • Choice: Added <Suspense fallback={null}><LanguageSwitcher /></Suspense> to the right side of the LegalLayout Nav. Applied justify-between to the nav container for Logo left / LanguageSwitcher right placement. Kept Server Component (async); Client Component (LanguageSwitcher) is automatically handled by RSC→CC boundary.
  • Verification: jest 1357 passing (+1), tsc/lint clean
  • Code Paths: frontend/src/components/layout/LegalLayout.tsx (+8 lines), frontend/src/components/layout/__tests__/LegalLayout.test.tsx (+11 lines, LanguageSwitcher mock + mount verification)
  • PR: #161 (fa1d68a, Squash merge)

D2: GuestNav / SharedLayout Excluded from Sprint 132 Scope (Policy Decision)

  • Context: /guest, /guest/preview/[slug] (GuestNav), /shared/[token] (SharedLayout) also have LanguageSwitcher unmounted. Reconnaissance identified 5 candidates.
  • Choice: By user policy decision, only LegalLayout was fixed. Guest pages can switch language via LanguageSwitcher on Landing (/) before entry; Shared links are read-only views where toggling is not necessary.

Metrics

ItemValue
Total changes+19 lines, -2 lines (2 files)
jest1357 passing (1356 → +1)
tscclean
lintclean
CriticOmitted (5th repetition of existing pattern, 0 new logic — same policy as Sprint 131)
PR#161 Squash merge fa1d68a
Commits2 (before squash: 29b6b8f code + ef5609d ADR)
CI31 pass / 7 skipping / 0 fail
end_commitfa1d68a