
Introduction
Modern apps often target users across different countries and cultures. Because of this, supporting multiple languages, formats, and layouts is no longer optional. Internationalisation (i18n) prepares your Flutter app for multiple locales, while localisation (l10n) provides the translated and region-specific content. In this guide, you will learn how i18n and l10n work in Flutter, how to set them up correctly, and how to avoid common mistakes when building global-ready apps.
Why i18n and l10n Matter in Flutter Apps
Language and regional support directly affect usability and adoption. Therefore, proper localisation improves both user experience and market reach.
• Reach a global audience
• Improve accessibility and inclusivity
• Increase user trust
• Support region-specific formats
• Reduce future refactoring costs
As a result, i18n should be considered early in app design.
Understanding i18n vs l10n
Although the terms are related, they serve different purposes.
• Internationalisation (i18n) prepares the app for multiple locales
• Localisation (l10n) provides translated text and regional data
• i18n is a technical setup
• l10n is content and formatting
• Both work together
Flutter supports both concepts natively.
Flutter’s Localisation System
Flutter uses the intl package and code generation to manage translations.
• Locale-aware widgets
• Generated localisation classes
• Strong compile-time checks
• Easy integration with Material and Cupertino
This system keeps translations structured and type-safe.
Adding Required Dependencies
Start by enabling Flutter’s localisation support.
dependencies:
flutter_localizations:
sdk: flutter
intl: ^0.19.0
These packages provide core localisation features.
Configuring MaterialApp for Locales
Next, configure your app to support multiple locales.
MaterialApp(
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en'),
Locale('es'),
Locale('de'),
],
);
This setup enables Flutter to load the correct locale automatically.
Creating ARB Files for Translations
Flutter uses ARB (Application Resource Bundle) files to store translations.
{
"title": "Welcome",
"logout": "Log out"
}
Each locale has its own ARB file, such as app_en.arb or app_de.arb.
Accessing Localised Strings
Generated localisation classes provide type-safe access.
Text(AppLocalizations.of(context)!.title);
This approach avoids hard-coded strings throughout the app.
Handling Plurals and Parameters
Real-world apps often need dynamic messages.
"itemsCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}"
Text(AppLocalizations.of(context)!.itemsCount(count));
Plurals and parameters improve natural language flow.
Formatting Dates, Numbers, and Currencies
Localisation goes beyond text.
• Date formats vary by region
• Decimal separators differ
• Currency symbols change
• Text direction may switch
DateFormat.yMMMd(Localizations.localeOf(context).toString())
.format(DateTime.now());
Using locale-aware formatting avoids confusion.
Supporting Right-to-Left Languages
Some languages require RTL layouts.
• Arabic
• Hebrew
• Persian
Flutter handles RTL automatically when the locale is set, provided layouts avoid hard-coded alignment.
Changing Language at Runtime
Many apps allow users to switch languages manually.
• Store selected locale in state
• Rebuild MaterialApp with new locale
• Persist preference locally
setState(() {
_locale = const Locale('de');
});
Runtime switching improves user control.
Organising Translation Keys
Good structure keeps translations manageable.
• Group related keys
• Avoid duplicate phrases
• Use clear, descriptive names
• Keep ARB files consistent
This prevents translation drift over time.
Common i18n Mistakes to Avoid
Hard-Coded Strings
Text inside widgets should always come from localisation files.
Ignoring Text Expansion
Some languages require more space.
Forgetting RTL Testing
Layouts must be tested with RTL locales.
Avoiding these issues saves time later.
Testing Localisation
Testing ensures correctness across locales.
• Switch device language
• Test different screen sizes
• Validate plural forms
• Check date and number formats
Testing catches issues that static checks miss.
When i18n Is Especially Important
Internationalisation is critical when you build:
• Consumer-facing apps
• E-commerce platforms
• Educational tools
• Government or public services
• Global SaaS products
In these cases, localisation directly impacts success.
Conclusion
Internationalisation and localisation in Flutter allow you to build apps that feel native to users worldwide. By setting up i18n early, managing translations properly, and handling regional formats correctly, you can avoid costly rewrites and deliver a polished global experience. If you are building resilient mobile architectures, read Building Offline-First Flutter Apps: Local Storage and Sync. For advanced UI control, see Custom Animations with AnimationController & Tween. You can also explore the Flutter internationalisation documentation and the intl package documentation. With the right setup, Flutter localisation becomes a powerful asset rather than a maintenance burden.
1 Comment