Configures and implements internationalization (i18n) and localization (l10n) in a Flutter application. This skill manages dependency injection (flutter_localizations, intl), code generation configuration (l10n.yaml), root widget setup (MaterialApp, CupertinoApp, or WidgetsApp), .arb translation file management, and platform-specific configurations (iOS Xcode project updates). It ensures proper locale resolution and prevents common assertion errors related to missing localization delegates in specific widgets like TextField and CupertinoTabBar.
-
Configure Dependencies
Update pubspec.yaml to include required packages and enable code generation.
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
flutter:
generate: true
-
Configure Code Generation
Create an l10n.yaml file in the project root to define the localization tool's behavior.
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
synthetic-package: false
-
Define Supported Locales
STOP AND ASK THE USER: "Which languages and regions do you want to support? Please provide a list of language codes (e.g., 'en', 'es', 'zh_Hans_CN')."
-
Create ARB Files
Generate the template .arb file (e.g., lib/l10n/app_en.arb) and corresponding translation files. Implement placeholders, plurals, and selects as needed.
{
"helloWorld": "Hello World!",
"@helloWorld": {
"description": "Standard greeting"
},
"greeting": "Hello {userName}",
"@greeting": {
"description": "Greeting with a parameter",
"placeholders": {
"userName": {
"type": "String"
}
}
},
"nWombats": "{count, plural, =0{no wombats} =1{1 wombat} other{{count} wombats}}",
"@nWombats": {
"placeholders": {
"count": {
"type": "num",
"format": "compact"
}
}
}
}
-
Initialize Root App
Import the generated localizations file and configure the root MaterialApp or CupertinoApp.
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:your_app_name/l10n/app_localizations.dart'; // Adjust path based on synthetic-package setting
// Inside your root widget build method:
return MaterialApp(
title: 'Localized App',
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''), // English
Locale('es', ''), // Spanish
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
],
home: const MyHomePage(),
);
-
Handle Isolated Widgets (If Applicable)
If a TextField or CupertinoTabBar throws a missing MaterialLocalizations or Localizations ancestor error, inject a Localizations widget directly above it.
Localizations(
locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[
DefaultWidgetsLocalizations.delegate,
DefaultMaterialLocalizations.delegate,
DefaultCupertinoLocalizations.delegate,
],
child: CupertinoTabBar(
items: const <BottomNavigationBarItem>[...],
),
)
-
Configure iOS Project
STOP AND ASK THE USER: "Does this project target iOS? If yes, I will provide instructions for updating the Xcode project."
If yes, instruct the user to:
- Open
ios/Runner.xcodeproj in Xcode.
- Select the
Runner project in the Project Navigator.
- Go to the
Info tab.
- Under Localizations, click
+ to add all supported languages.
-
Validate and Fix
Run flutter gen-l10n. Verify that app_localizations.dart is generated successfully. If compilation fails with "No MaterialLocalizations found" or "CupertinoTabBar requires a Localizations parent", traverse up the widget tree from the failing widget and ensure localizationsDelegates are properly provided.