Skip to content

feat(i18n): en/ko localization with dictionary + cookie-driven provider - #104

Open
sigco3111 wants to merge 1 commit into
Younesfdj:masterfrom
sigco3111:i18n-en-ko
Open

feat(i18n): en/ko localization with dictionary + cookie-driven provider#104
sigco3111 wants to merge 1 commit into
Younesfdj:masterfrom
sigco3111:i18n-en-ko

Conversation

@sigco3111

Copy link
Copy Markdown

Summary

This PR introduces full English + Korean localization for GitFut without
changing the visual identity of any surface.

  • Translation source-of-truth: lib/i18n/dict/{en,ko}.ts — every user-visible
    string (scoring archetypes, playstyle names, metric labels, style and
    workRate reasons, scout form copy, how-it-works modal, duel view,
    error/404 screens, country names) lives in a typed dictionary.
  • Cookie-driven provider: LocaleProvider reads the gitfut_locale cookie on
    the server (so the first paint is correctly localized) and writes it on
    the client when the user toggles. reflects the active locale.
  • OG cards / JSON API: locked to EN by passing locale="en" to buildCard()
    — social cards carry the brand read, not the viewer's locale.
  • Drift detection: tests/i18n.test.ts asserts every key in en exists in ko
    (and vice versa); adding a key to one without the other now fails CI.

What changed

  • New lib/i18n/ directory (8 modules, ~700 LOC): locale negotiation,
    dictionary loader, translator API (t("...", locale, params), typed
    helpers for archetype/playstyle/metric/duel stat-row/duel receipt/country
    name), server resolver, client cookie helpers, hooks.
  • New components/LocaleToggle.tsx mounted in the AppShell top-right corner
    next to the Star button.
  • Scoring engine now accepts a locale parameter across buildCard,
    derivePlaystyles, deriveSkillMoves, deriveWeakFoot, deriveWorkRate,
    deriveStyle, deriveMetrics. Tests stay identical (default locale is EN).
  • lib/duel.ts (computeDuel) now takes a locale so stat-row and receipt
    labels localize; lib/og/renderCard keeps EN because OG cards are brand read.
  • lib/countries.ts is left untouched (auto-generated); t.countryName(code,
    locale) reads from the dictionary with EN fallback.
  • 250-country dictionary is identical in shape across locales (mirrored
    keys) — KO dictionary overrides priority subset (Korea, Japan, USA, WC26
    hosts, EU neighbours, etc.) and falls back to EN for the rest.

Tested

tests/i18n.test.ts — 19 new tests covering dictionary loading, fallback
for unknown locale, key-set parity, locale negotiation (Accept-Language
parsing, quality factors, region stripping), isLocale / localeFromCookie
guards, t.stat / t.metric / t.style / t.playstyle / t.workRate_reason /
t.attribute.skillMoves / t.attribute.weakFoot, @locked key prefix (always
returns EN), formatCount / formatInt accepting the locale.

npm test → 296/296 passing. npx tsc --noEmit → 0 errors.

Notes

  • I leaned on the project's existing single-source-of-truth patterns
    (METRIC_LABELS, FINISH_LABELS) rather than introducing a new i18n library.
    The translator is plain TypeScript so there's no new dependency.
  • The footer credit, mascot SVG, and "OFFSIDE" tier art are styled English
    brand reads that don't localize — left as-is.
  • HowItWorksModal.laws array got its bullets/laws translated (3 entries +
    hero + reads section + ladder labels).

- Add lib/i18n/ (Locale union, dictionaries, translator API, server + client)
- Wire LocaleProvider into app/layout.tsx, hydrate <html lang> from cookie
- Convert ScoutForm, LoadingScreen, HowItWorksModal, ResultView, DuelView
  (incl. duel stat row labels + receipts + share/draw headlines),
  FlagPicker (country names), 404/error pages to the i18n API
- Translate the scoring engine's archetype blurbs, playstyle names,
  metric labels, style and workRate reasons
- Add LocaleToggle in the AppShell corner (cookie write + custom event)
- Pin buildCard() locale='en' for OG / JSON endpoints (locked keys: t('@...'))
- Add 250-entry countries table (priority KO overrides + EN fallback)
- Add tests/i18n.test.ts covering dictionary parity, fallback chains,
  negotiateLocale, format helpers
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.

1 participant