Flutter localization
Skill almasumdev/awesome-flutter-agent-skills/.github/skills/ui/flutter-localization
Setup Flutter localization with flutter_localizations, ARB files, intl plurals/genders/dates, RTL support, and dynamic locale switching. Use this when adding or auditing i18n.From its SKILL.md
npx -y skills add almasumdev/awesome-flutter-agent-skills --skill flutter-localizationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.2 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Flutter Localization & Internationalization
Instructions
Design every string as localizable from day one. Retrofitting i18n costs 10× more than doing it upfront.
1. Setup
pubspec.yaml:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
flutter:
generate: true # enables gen_l10n
Create l10n.yaml:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
nullable-getter: false
Add to MaterialApp:
MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
// ...
);
2. ARB Files
lib/l10n/app_en.arb:
{
"@@locale": "en",
"welcome": "Welcome, {name}!",
"@welcome": {
"description": "Greeting on the home screen",
"placeholders": { "name": { "type": "String", "example": "Alex" } }
},
"itemsCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
"@itemsCount": {
"placeholders": { "count": { "type": "int" } }
}
}
Consume:
Text(AppLocalizations.of(context).welcome('Alex'))
Text(AppLocalizations.of(context).itemsCount(cartItems.length))
3. Plurals and Genders
Always use ICU syntax — never string-concatenate for pluralization:
"messagesFrom": "{gender, select, male{He sent {count, plural, one{a message} other{{count} messages}}} female{She sent {count, plural, one{a message} other{{count} messages}}} other{They sent {count, plural, one{a message} other{{count} messages}}}}"
4. Dates, Numbers, Currency
Use intl:
DateFormat.yMMMd(Localizations.localeOf(context).toString()).format(date);
NumberFormat.currency(locale: 'de_DE', symbol: '€').format(1234.5);
NumberFormat.compact(locale: 'en').format(12500); // "12.5K"
5. RTL Support
- Use logical edges:
EdgeInsetsDirectional.only(start: 16)instead ofEdgeInsets.only(left: 16). - Use
AlignmentDirectional,PositionedDirectional,BorderRadiusDirectional. - Icons that indicate direction (arrows, back chevrons) should use
Icons.arrow_back_ios_newwithtextDirectionaware widgets, or mirror viaTransform(transform: Matrix4.rotationY(math.pi))when locale is RTL. - Test by forcing
Directionality(textDirection: TextDirection.rtl, child: ...)in widget tests.
6. Dynamic Locale Switching
Expose locale via a provider and listen in MaterialApp:
final localeProvider = StateProvider<Locale?>((_) => null);
class App extends ConsumerWidget {
@override
Widget build(BuildContext ctx, WidgetRef ref) {
final locale = ref.watch(localeProvider);
return MaterialApp(
locale: locale,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: const HomeScreen(),
);
}
}
Persist the chosen locale in shared_preferences and restore on boot.
7. Translator Workflow
- Keep
app_en.arbas the source of truth; translators editapp_<locale>.arb. - Use tools like Crowdin, Lokalise, or Phrase to sync ARB files.
- Run
flutter gen-l10n(auto-runs on build) and commit generated.dart— or gitignore and regenerate in CI.
8. Common Pitfalls
- Concatenating strings (
'Hello, ' + name) — breaks word order in many languages. - Using
.toString()on numbers/dates for display — ignores locale. - Hardcoded
EdgeInsets.only(left: ...)— breaks RTL. - Forgetting to add a new locale to
supportedLocales. - Not testing at 200% text scale with the longest translation (German, Finnish commonly expand 30–40%).
9. Checklist
-
flutter_localizations+intlconfigured;flutter: generate: true. - Every user-visible string is in an ARB file.
- Plurals use ICU, not
if/else. - RTL tested with at least one RTL locale (Arabic / Hebrew).
- Dynamic locale switching works and persists.
- CI regenerates
app_localizations.dartbefore running tests.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.