Skip to content

Frontend Internationalization (i18n)

Architecture

Localization is provided by I18nProvider (frontend/jenga/src/provider/I18nProvider.tsx) using i18next.

The provider exposes: - t(key, options?) translation accessor - language() reactive accessor - changeLanguage(lng) command

Library: i18next

i18next is an internationalization library that provides key-based translations and a runtime language switch. It maintains an internal translation catalog ("resources") and emits events such as languageChanged when the active language changes.

In this frontend, i18next is used as: - the translation engine behind t(key, options?) - the source of truth for the current language - the event source that drives reactive language updates in I18nProvider

Lifecycle

Initialization sequence:

  1. provider mounts
  2. i18next is initialized once (isInitialized guard)
  3. resources are registered (en, de)
  4. language change listener is attached
  5. ready signal is set to true
  6. app content is rendered only when ready is true

This avoids rendering untranslated fallback strings during bootstrap.

Resources

Locale files: - frontend/jenga/src/locales/en.json - frontend/jenga/src/locales/de.json

Key parity: - user-facing keys are maintained in both files in the same change (maintained convention, not enforced automatically)

This prevents asymmetric UI behavior between languages and keeps guide/tooling labels stable independent of active locale.

Reactivity

The provider implementation makes translations reactive by reading language() inside t(...).

Effect: - components calling t(...) rerender on language switch without custom invalidation code

Tradeoff: - all visible translated nodes rerender on language change, which is expected and acceptable for this app size

Fallback Behavior

Provider config uses: - returnNull: false - returnEmptyString: false

translated || key fallback prevents empty UI labels and helps diagnose missing keys quickly.

Operational Notes

The current implementation follows these conventions: - user-facing strings are not hardcoded in components/providers/pages - translation keys are namespaced (ticketInfo.*, errors.*, guide.*) for maintainability - translation keys are typically defined before wiring the UI for new feature work

Verification

Typical verification for i18n changes: 1. switching between en and de 2. checking dialogs, alerts, form labels, and guide text 3. confirming no raw keys are visible in runtime UI