flutter-internationalization
Scannednpx machina-cli add skill MADTeacher/mad-agents-skills/flutter-internationalization --openclawFlutter 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
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
Manual/Custom - Maximum flexibility
- Best for: Very simple apps, custom workflows
- Uses: Direct Map-based lookups
- See: Custom localizations
Setup gen-l10n
1. Add Dependencies
Update pubspec.yaml:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
Run:
flutter pub add flutter_localizations --sdk=flutter
flutter pub add intl:any
2. Enable Code Generation
Add to pubspec.yaml:
flutter:
generate: true
3. Configure l10n.yaml
Create l10n.yaml in project root:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
For advanced options, see l10n-config.md.
4. Create ARB Files
Create directory lib/l10n/.
Template file lib/l10n/app_en.arb:
{
"helloWorld": "Hello World!",
"@helloWorld": {
"description": "Greeting message"
}
}
Translation file lib/l10n/app_es.arb:
{
"helloWorld": "¡Hola Mundo!"
}
For complete ARB format, see arb-format.md.
5. Generate Code
Run:
flutter gen-l10n
Or run app to trigger auto-generation:
flutter run
6. Configure MaterialApp
Import and setup:
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:
Text(AppLocalizations.of(context)!.helloWorld)
Message Types
Simple Messages
No parameters:
{
"welcome": "Welcome to our app",
"@welcome": {
"description": "Welcome message"
}
}
Placeholder Messages
With parameters:
{
"greeting": "Hello {userName}!",
"@greeting": {
"description": "Personalized greeting",
"placeholders": {
"userName": {
"type": "String",
"example": "Alice"
}
}
}
}
Use in code:
Text(AppLocalizations.of(context)!.greeting('Alice'))
Plural Messages
Based on count:
{
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
"@itemCount": {
"placeholders": {
"count": {
"type": "int"
}
}
}
}
Use in code:
Text(AppLocalizations.of(context)!.itemCount(5))
Select Messages
Based on string value:
{
"pronoun": "{gender, select, male{he} female{she} other{they}}",
"@pronoun": {
"placeholders": {
"gender": {
"type": "String"
}
}
}
}
Use in code:
Text(AppLocalizations.of(context)!.pronoun('male'))
Number and Date Formatting
Numbers
Format numbers automatically:
{
"price": "Price: {value}",
"@price": {
"placeholders": {
"value": {
"type": "int",
"format": "simpleCurrency"
}
}
}
}
Format options: compact, currency, simpleCurrency, decimalPattern, etc.
Dates
Format dates automatically:
{
"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.
Advanced Topics
Locale Override
Override locale for specific widgets:
Localizations.override(
context: context,
locale: const Locale('es'),
child: CalendarDatePicker(...),
)
Custom Locale Definitions
For complex locales (Chinese, French regions):
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:
MaterialApp(
localeResolutionCallback: (locale, supportedLocales) {
// Always accept user's locale
return locale;
},
)
Access Current Locale
Get current app locale:
Locale myLocale = Localizations.localeOf(context);
Setup intl Package
Manual Setup
- Add dependencies (same as gen-l10n)
- Create localization class:
class DemoLocalizations {
DemoLocalizations(this.localeName);
static Future<DemoLocalizations> load(Locale locale) {
final String name = Intl.canonicalizedLocale(locale.toString());
return initializeMessages(name).then((_) => DemoLocalizations(name));
}
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations)!;
}
String get title {
return Intl.message(
'Hello World',
name: 'title',
desc: 'Title',
locale: localeName,
);
}
}
- Create delegate:
class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> {
const DemoLocalizationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
@override
Future<DemoLocalizations> load(Locale locale) => DemoLocalizations.load(locale);
@override
bool shouldReload(DemoLocalizationsDelegate old) => false;
}
- Generate ARB files:
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:
class DemoLocalizations {
DemoLocalizations(this.locale);
final Locale locale;
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations)!;
}
static const _localizedValues = <String, Map<String, String>>{
'en': {'title': 'Hello World'},
'es': {'title': 'Hola Mundo'},
};
String get title {
return _localizedValues[locale.languageCode]!['title']!;
}
}
Best Practices
- Use gen-l10n for new projects - simpler, safer, better tooling
- Add descriptions to ARB entries - provides context for translators
- Format numbers/dates with format types - automatic locale handling
- Test all locales - verify formatting, RTL, and translations
- Use pluralization - handle count variations correctly
- Keep messages short - easier to translate, more consistent
- Don't concatenate strings - use placeholders instead
- 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
Source
git clone https://github.com/MADTeacher/mad-agents-skills/blob/main/flutter-internationalization/SKILL.mdView on GitHub Overview
A comprehensive guide to adding internationalization (i18n) to Flutter apps. It covers setup, configuration, message management, and formatting for numbers and dates across locales, with advanced topics like locale override and custom language support.
How This Skill Works
The guide walks you through choosing between gen-l10n and the intl package, then shows how to enable code generation or manual localization. It covers ARB files, code generation with flutter gen-l10n, and wiring MaterialApp with the necessary localization delegates and supportedLocales.
When to Use It
- Add localization support to a Flutter app
- Translate UI text into multiple languages
- Format numbers and dates for different locales
- Configure multi-language support for Material and Cupertino widgets
- Migrate an app from a manual i18n approach to gen-l10n or intl
Quick Start
- Step 1: Pick gen-l10n (recommended) or intl and add dependencies in pubspec.yaml
- Step 2: Enable code generation and set up ARB files (lib/l10n) and l10n.yaml
- Step 3: Run flutter gen-l10n and configure MaterialApp with localization delegates; use AppLocalizations in widgets
Best Practices
- Choose gen-l10n for most projects to automate code generation and reduce boilerplate
- Keep ARB files under lib/l10n and provide clear descriptions for keys
- Use well-named keys (e.g., helloWorld, greeting) and metadata for translators
- Test across locales, including RTL support and locale overrides
- Configure localization delegates and supportedLocales in MaterialApp
Example Use Cases
- An e-commerce Flutter app localized into English, Spanish, and French using ARB files and AppLocalizations
- An app that formats currency, dates, and numbers according to the user’s locale
- An app with locale overrides to restrict available languages per region
- A legacy app migrated from Intl.message to gen-l10n with automated codegen
- A cross-platform app delivering localized UI across Material and Cupertino widgets