Localization (EN/FR) – strategy and policy
HealthArchive.ca supports English and French UI copy:
- English is the default (canonical URLs are unprefixed, e.g.
/archive). - French lives under
/fr/...and is a convenience-only, automated translation. - English governs: if there is any inconsistency, the English version is authoritative.
- Archived snapshots are never translated (they remain as-captured).
Locale codes
- English:
en-CA - French:
fr-CA
See src/lib/i18n.ts for locale helpers.
Routing and URLs
- The app is structured under
src/app/[locale]/.... src/proxy.tskeeps English canonical URLs unprefixed and routes French under/fr.- Static assets and downloads (e.g.
.md) are not localized (seelocalizeHref()logic).
Translation safety posture
French is explicitly labeled as alpha and may contain errors:
- Global banner:
src/components/i18n/FrenchTranslationBanner.tsx - Policy pages:
src/components/policy/EnglishControlsNotice.tsx+ French summaries
SEO:
/fr/...pages are markednoindex(seesrc/app/[locale]/layout.tsx).- Locale alternates are declared per route (
hreflangforen-CAandfr-CA) viabuildPageMetadata()insrc/lib/metadata.ts. - Release steps are tracked in
docs/deployment/bilingual-release-checklist.md.
Where copy lives
Prefer reusing canonical copy instead of duplicating it:
- Canonical mission + disclaimers:
src/lib/siteCopy.ts(getSiteCopy(locale)) - Small localized values:
src/lib/localized.ts(pickLocalized(locale, { en, fr })) - Locale access in client components:
src/components/i18n/LocaleProvider.tsx(useLocale()) - Locale access in server components:
src/lib/resolveLocale.ts(resolveLocale(params))
Editing guidelines
- Treat the English text as the source of truth.
- Keep French meaning conservative and aligned with the safety posture:
- independent, non-governmental
- not medical advice / not current guidance
- archived content may be incomplete/outdated
- Keep the “English governs” language intact on
/terms,/privacy,/governance.
Testing
Many route components are async server components. In tests, render them like: