--- description: "Localization / i18n conventions for {{PROJECT_NAME}}" globs: ["lib/l10n/**", "lib/**/*.dart", "test/**/*.dart"] alwaysApply: false --- # Localization Standards — {{PROJECT_NAME}} ## Supported locales: {{LOCALES_LIST}} ## Setup - Use Flutter's built-in `AppLocalizations` (generated from `.arb` files) - ARB files: `lib/l10n/app_en.arb`, `lib/l10n/app_fr.arb`, etc. - Never hardcode user-facing strings — always use `context.l10n.stringKey` ## AppLocalizations access ```dart // In widgets: final l10n = AppLocalizations.of(context)!; Text(l10n.welcomeMessage) // ✅ // Extension for convenience: extension LocalizationX on BuildContext { AppLocalizations get l10n => AppLocalizations.of(this)!; } Text(context.l10n.welcomeMessage) // ✅ ``` ## ARB file format ```json { "welcomeMessage": "Welcome back, {name}!", "@welcomeMessage": { "description": "Shown on home screen after login", "placeholders": { "name": { "type": "String", "example": "Alice" } } }, "itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}", "@itemCount": { "placeholders": { "count": { "type": "int" } } } } ``` ## Rules - **NEVER** hardcode user-facing strings as string literals in widget files - **Technical keys** (route paths, storage/analytics keys, JSON fields): one shared module (e.g. `lib/core/constants/app_strings.dart`) — no duplicated literals across features - All new strings added to ALL locale ARB files simultaneously — broken translations break builds - Use ICU message format for plurals and gendered strings - Date/time formatting: use `intl` package `DateFormat` — never `date.toString()` - Currency: use `NumberFormat.currency(locale: locale)` — never manual formatting - RTL support: wrap with `Directionality` where needed; test with Arabic locale