Keyboard Shortcuts

j / kScroll down / up
ggScroll to top
GScroll to bottom
/Open search
?Show this help
EscClose search / help
n / NNext / previous section
hGo to landing
dGo to docs
:Command mode — type section name

Press ? or Esc to close

Deep Dives

Localization

Loaded once at startup, cached locally, refreshed from remote when available. UI always reads from context.l10n — it never knows where strings came from.

3-source priority: cache → remote → asset

StepSourceWhen used
1CacheAlways tried first — instant load, zero network wait
2RemoteCache miss or stale — fetches fresh strings (API / Firebase Remote Config)
3AssetFallback — bundled JSON, always available, never fails
Future> load(Locale locale) async {
  return await cache.load(locale)
      ?? await remote.load(locale)   // saves to cache on success
      ?? await asset.load(locale);   // always works
}

Asset format

// assets/i18n/en.json — flat key → ICU string
{
  "welcome": "Welcome, {name}!",
  "retry":   "Try again"
}

UI usage

Text(context.l10n.t('welcome', args: {'name': 'Amir'}))

Runtime flow

app start / locale change
  → LocalizationCubit.changeLocale()
    → LocalizationRepository.load()
      → cache? → yes: use it
      → no: remote? → yes: use + save cache
      → no: asset → always works
        → AppLocalization emitted
          → MaterialApp rebuilds
            → all context.l10n calls updated
Constraints:
No static access (AppStrings.welcome — forbidden).
No code generation. No feature-owned translation files.
Formatting (plurals, dates) happens inside AppLocalization.t() only.
UI imports nothing from the localization layer directly.
sam's arch — A Pragmatic Flutter Architecture