Flutter Internationalization: A Complete Guide to i18n in 2026
Learn how to internationalize your Flutter app with the intl package, ARB files, and localization delegates. A practical guide to supporting multiple languages.
Published on • September 16, 2026
AI Assistant

Reaching a global audience means your Flutter app needs to speak their language. Flutter’s internationalization (i18n) system provides a robust framework for supporting multiple languages, including RTL layouts, date/number formatting, and pluralization.
Why Internationalize?
- Market reach: 75% of the world’s population doesn’t speak English as a first language.
- User experience: Native language support increases engagement and retention.
- App store optimization: Localized apps rank higher in regional stores.
- Legal requirements: Some markets require local language support.
Setup with flutter_localizations
Step 1: Add Dependencies
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
Step 2: Configure MaterialApp
import 'package:flutter_localizations/flutter_localizations.dart';
MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English
const Locale('es', ''), // Spanish
const Locale('ja', ''), // Japanese
],
home: MyHomePage(),
);
In Flutter 3.47 with standalone packages, this simplifies to:
import 'package:material_ui/material_ui.dart';
localizationsDelegates: GlobalMaterialLocalizations.delegates,
ARB Files
Application Resource Bundle (ARB) files store translations. Create lib/l10n/app_en.arb:
{
"@@locale": "en",
"helloWorld": "Hello World!",
"@helloWorld": {
"description": "The greeting displayed on the home screen"
},
"itemCount": "{count, plural, =0{No items} =1{One item} other{{count} items}}",
"@itemCount": {
"description": "The count of items",
"placeholders": {
"count": "int"
}
}
}
And lib/l10n/app_es.arb:
{
"@@locale": "es",
"helloWorld": "¡Hola Mundo!",
"itemCount": "{count, plural, =0{Sin elementos} =1{Un elemento} other{{count} elementos}}"
}
Generating Localizations
Configure l10n.yaml in your project root:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
Run the generator:
flutter gen-l10n
Using Translations
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
Text(
AppLocalizations.of(context)!.helloWorld,
)
Advanced Features
Placeholders
{
"greeting": "Hello, {name}!"
}
Text(AppLocalizations.of(context)!.greeting('Alice'))
Plurals
{
"itemsSelected": "{count, plural, =0{No items selected} =1{1 item selected} other{{count} items selected}}"
}
Dates and Numbers
The intl package provides locale-aware formatting:
import 'package:intl/intl.dart';
// Date formatting
final dateFormat = DateFormat.yMMMd(Localizations.localeOf(context).toString());
final formatted = dateFormat.format(DateTime.now());
// Number formatting
final numberFormat = NumberFormat.compact(locale: 'ja');
final formatted = numberFormat.format(1234567); // "123.4万"
RTL Support
Flutter automatically handles right-to-left layouts for languages like Arabic and Hebrew. Key considerations:
TextDirectionis set automatically based on locale.- Use
Directionalitywidget for explicit control. EdgeInsetsand layout widgets respect direction automatically.
Accessibility
Internationalization works hand-in-hand with accessibility:
- Screen readers use the correct locale for pronunciation.
- Semantic labels can be localized.
- Date and number formatting ensures screen readers announce values correctly.
Testing Internationalization
Unit Tests
testWidgets('displays localized text', (tester) async {
await tester.pumpWidget(
MaterialApp(
localizationsDelegates: [AppLocalizations.delegate],
supportedLocales: [Locale('es')],
home: MyWidget(),
),
);
expect(find.text('¡Hola Mundo!'), findsOneWidget);
});
Golden Tests
Golden tests can verify localized layouts render correctly across languages.
Best Practices
- Start early: Adding i18n to an existing codebase is harder than building it in from the start.
- Use ICU message format: Supports plurals, select, and gender.
- Keep translations separate: Don’t hardcode strings in widgets.
- Test all supported locales: Different languages have different text lengths and layouts.
- Consider cultural differences: Colors, icons, and imagery may need localization beyond text.
Sources: