--- name: flutter-internationalization description: Complete guide for internationalizing Flutter apps using gen-l10n and intl packages. Use when Claude needs to add localization support to Flutter applications, translate UI text, format numbers/dates for different locales, or configure multi-language support for Material/Cupertino apps. --- # Flutter Internationalization ## Overview Comprehensive guide for adding internationalization (i18n) to Flutter applications. Covers setup, configuration, message management, number/date formatting, and advanced topics like locale override and custom language support. ## Quick Start Choose approach based on app needs: **gen-l10n (Recommended)** - Modern, automated, code generation - Best for: Most new projects, teams, complex apps - Uses: ARB files, automated code generation - See: [Setup gen-l10n](#setup-gen-l10n) **intl package** - Manual control, code-based - Best for: Simple apps, legacy projects, full control - Uses: `Intl.message()` code, manual translation files - See: [Setup intl package](#setup-intl-package) **Manual/Custom** - Maximum flexibility - Best for: Very simple apps, custom workflows - Uses: Direct Map-based lookups - See: [Custom localizations](#custom-localizations) ## Setup gen-l10n ### 1. Add Dependencies Update `pubspec.yaml`: ```yaml dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter intl: any ``` Run: ```bash flutter pub add flutter_localizations --sdk=flutter flutter pub add intl:any ``` ### 2. Enable Code Generation Add to `pubspec.yaml`: ```yaml flutter: generate: true ``` ### 3. Configure l10n.yaml Create `l10n.yaml` in project root: ```yaml arb-dir: lib/l10n template-arb-file: app_en.arb output-localization-file: app_localizations.dart ``` For advanced options, see [l10n-config.md](references/l10n-config.md). ### 4. Create ARB Files Create directory `lib/l10n/`. **Template file** `lib/l10n/app_en.arb`: ```json { "helloWorld": "Hello World!", "@helloWorld": { "description": "Greeting message" } } ``` **Translation file** `lib/l10n/app_es.arb`: ```json { "helloWorld": "¡Hola Mundo!" } ``` For complete ARB format, see [arb-format.md](references/arb-format.md). ### 5. Generate Code Run: ```bash flutter gen-l10n ``` Or run app to trigger auto-generation: ```bash flutter run ``` ### 6. Configure MaterialApp Import and setup: ```dart import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'l10n/app_localizations.dart'; MaterialApp( localizationsDelegates: [ AppLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: [ Locale('en'), Locale('es'), ], home: MyHomePage(), ) ``` ### 7. Use Localizations Access in widgets: ```dart Text(AppLocalizations.of(context)!.helloWorld) ``` ## Message Types ### Simple Messages No parameters: ```json { "welcome": "Welcome to our app", "@welcome": { "description": "Welcome message" } } ``` ### Placeholder Messages With parameters: ```json { "greeting": "Hello {userName}!", "@greeting": { "description": "Personalized greeting", "placeholders": { "userName": { "type": "String", "example": "Alice" } } } } ``` Use in code: ```dart Text(AppLocalizations.of(context)!.greeting('Alice')) ``` ### Plural Messages Based on count: ```json { "itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}", "@itemCount": { "placeholders": { "count": { "type": "int" } } } } ``` Use in code: ```dart Text(AppLocalizations.of(context)!.itemCount(5)) ``` ### Select Messages Based on string value: ```json { "pronoun": "{gender, select, male{he} female{she} other{they}}", "@pronoun": { "placeholders": { "gender": { "type": "String" } } } } ``` Use in code: ```dart Text(AppLocalizations.of(context)!.pronoun('male')) ``` ## Number and Date Formatting ### Numbers Format numbers automatically: ```json { "price": "Price: {value}", "@price": { "placeholders": { "value": { "type": "int", "format": "simpleCurrency" } } } } ``` Format options: `compact`, `currency`, `simpleCurrency`, `decimalPattern`, etc. ### Dates Format dates automatically: ```json { "eventDate": "Event on {date}", "@eventDate": { "placeholders": { "date": { "type": "DateTime", "format": "yMMMd" } } } } ``` Format options: `yMd`, `yMMMd`, `yMMMMd`, `Hm`, etc. For complete formatting options, see [number-date-formats.md](references/number-date-formats.md). ## Advanced Topics ### Locale Override Override locale for specific widgets: ```dart Localizations.override( context: context, locale: const Locale('es'), child: CalendarDatePicker(...), ) ``` ### Custom Locale Definitions For complex locales (Chinese, French regions): ```dart supportedLocales: [ Locale.fromSubtags(languageCode: 'zh'), Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'), Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'), ] ``` ### Locale Resolution Callback Control locale fallback: ```dart MaterialApp( localeResolutionCallback: (locale, supportedLocales) { // Always accept user's locale return locale; }, ) ``` ### Access Current Locale Get current app locale: ```dart Locale myLocale = Localizations.localeOf(context); ``` ## Setup intl Package ### Manual Setup 1. Add dependencies (same as gen-l10n) 2. Create localization class: ```dart class DemoLocalizations { DemoLocalizations(this.localeName); static Future load(Locale locale) { final String name = Intl.canonicalizedLocale(locale.toString()); return initializeMessages(name).then((_) => DemoLocalizations(name)); } static DemoLocalizations of(BuildContext context) { return Localizations.of(context, DemoLocalizations)!; } String get title { return Intl.message( 'Hello World', name: 'title', desc: 'Title', locale: localeName, ); } } ``` 3. Create delegate: ```dart class DemoLocalizationsDelegate extends LocalizationsDelegate { const DemoLocalizationsDelegate(); @override bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode); @override Future load(Locale locale) => DemoLocalizations.load(locale); @override bool shouldReload(DemoLocalizationsDelegate old) => false; } ``` 4. Generate ARB files: ```bash dart run intl_translation:extract_to_arb --output-dir=lib/l10n lib/main.dart dart run intl_translation:generate_from_arb --output-dir=lib/l10n lib/main.dart lib/l10n/intl_*.arb ``` ## Custom Localizations For maximum simplicity: ```dart class DemoLocalizations { DemoLocalizations(this.locale); final Locale locale; static DemoLocalizations of(BuildContext context) { return Localizations.of(context, DemoLocalizations)!; } static const _localizedValues = >{ 'en': {'title': 'Hello World'}, 'es': {'title': 'Hola Mundo'}, }; String get title { return _localizedValues[locale.languageCode]!['title']!; } } ``` ## Best Practices 1. **Use gen-l10n** for new projects - simpler, safer, better tooling 2. **Add descriptions** to ARB entries - provides context for translators 3. **Format numbers/dates** with format types - automatic locale handling 4. **Test all locales** - verify formatting, RTL, and translations 5. **Use pluralization** - handle count variations correctly 6. **Keep messages short** - easier to translate, more consistent 7. **Don't concatenate strings** - use placeholders instead 8. **Enable nullable-getter** to reduce null checks in user code ## Resources ### references/ **l10n-config.md** - Complete reference for `l10n.yaml` configuration options, including output directories, code generation settings, and locale handling. **arb-format.md** - Comprehensive guide to ARB file format, covering simple messages, placeholders, plurals, selects, and metadata. **number-date-formats.md** - Number and date formatting reference with format types, patterns, and locale-specific examples. ### assets/ Example templates and boilerplate code can be added here for common internationalization patterns. ## When to Use This Skill Use this skill when: - Adding localization support to a new Flutter app - Translating existing Flutter app to multiple languages - Configuring number/date formatting for different locales - Setting up RTL (right-to-left) language support - Implementing locale-specific layouts or widgets - Managing ARB files and translations - Troubleshooting localization issues - Adding custom language support beyond built-in locales - Optimizing app bundle size with deferred loading