Localization Setup
- Use Flutter’s built-in
flutter_localizationsandintlpackages - Enable
generate: trueinpubspec.yamlfor automatic code generation - Configure
l10n.yamlat project root:arb-dir: lib/l10n template-arb-file: app_en.arb output-localization-file: app_localizations.dart output-class: AppLocalizations nullable-getter: false
ARB File Structure
- Place all
.arbfiles inlib/l10n/ - Use
app_{locale}.arbnaming convention (e.g.,app_en.arb,app_es.arb,app_hi.arb) - The template ARB file (
app_en.arb) MUST contain@metadata for every key:{ "loginTitle": "Sign In", "@loginTitle": { "description": "Title on the login screen" }, "itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}", "@itemCount": { "description": "Item count with pluralization", "placeholders": { "count": { "type": "int" } } } } - Key naming: Use
featureName_contextformat (e.g.,settings_title,login_emailHint) - Group keys by feature in the ARB file with comment separators
Usage Rules
- Access strings via
context.l10n.keyNameusing aBuildContextextension - STRICTLY prohibit hardcoded user-facing strings anywhere in the codebase
- STRICTLY prohibit using
.l10nininitState()or outside the widget tree —contextmust be available - For date/time/number formatting, use
intlpackage formatters with the current locale
Plural & Select Forms
- Use ICU plural syntax for countable items:
{count, plural, =0{...} =1{...} other{...}} - Use ICU select syntax for gender/category:
{gender, select, male{...} female{...} other{...}} - Always include the
othercase as a fallback
RTL Support
- Use
DirectionalityandTextDirection-aware widgets - Prefer
EdgeInsetsDirectionaloverEdgeInsetsfor padding/margins - Use
start/endinstead ofleft/rightinMainAxisAlignmentandCrossAxisAlignment - Test with RTL locales during widget testing
Adding a New Language
- Create
app_{locale}.arbwith all keys translated - Run
flutter gen-l10n(or rely on auto-generation) - Add the
LocaletosupportedLocalesinMaterialApp - Verify with widget tests using the new locale