Skip to content
Blog

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:

  • TextDirection is set automatically based on locale.
  • Use Directionality widget for explicit control.
  • EdgeInsets and 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

  1. Start early: Adding i18n to an existing codebase is harder than building it in from the start.
  2. Use ICU message format: Supports plurals, select, and gender.
  3. Keep translations separate: Don’t hardcode strings in widgets.
  4. Test all supported locales: Different languages have different text lengths and layouts.
  5. Consider cultural differences: Colors, icons, and imagery may need localization beyond text.

Sources: