Multilingual Support in Flutter: From Setup to Implementation
- Yulian Airapetov
- 1 day ago
- 6 min read
Nowadays, apps often reach beyond a single country, and users expect a comfortable and understandable interface in their own language 🌐. However, many apps still operate without localization support, limiting their audience and preventing them from reaching their full potential on the global market 🚫
Lack of multilingual support can lead to lower user engagement 📉: it becomes harder for users to consume content, they lose trust in the app, and may stop using it. For example, an e-commerce app 🛒 available in only one language could lose a significant portion of international customers, even if its functionality is perfect.

Multilingual support isn’t just about translating text 📝. It also involves adapting date and time formats ⏰, currency 💰, numbers, and even content display styles to specific regions. Flutter provides flexible tools to implement these features, allowing developers to create apps that are understandable and user-friendly worldwide 🌏.
In this article, we’ll explore how to implement multilingual support in Flutter, from project setup to dynamic language switching 🔄. You’ll get a practical guide and tips to make your app truly global and convenient for users anywhere in the world 🌟.
i18n and l10n: What’s the Difference?
Whenever we talk about multilingual support in apps, two concepts always come up – i18n (internationalization) and l10n (localization). They often go hand in hand and are sometimes even confused with each other.
i18n
i18n is the process of preparing an app for multiple languages, even before any translations exist. Its goal is to make adding a new language simple and code-safe.
Key aspects:
Moving all texts and content into separate resources (files, databases)
Supporting date, time, number, and currency formats for different locales
Designing app architecture with the ability to add new languages in mind
Instead of hardcoding text in a widget:
Text('Hello, user!')
We use a resource:
Text(AppLocalizations.of(context).helloUser)
l10n
l10n is the process of localizing an app for a specific language or region. If i18n prepares the ground, l10n “plants the seeds”.
Key aspects:
Creating translations (e.g., English, French, Japanese)
Setting up localized formats (dates, numbers, currencies)
Considering cultural differences (e.g., different address formats or measurement units)
app_en.arb file for English translations:
{
"helloUser": "Hello, User!"
}
And app_de.arb for German:
{
"helloUser": "Hallo, Benutzer!"
}
How Flutter Handles Multilingual Support
Flutter provides a built-in mechanism that combines preparing for multilingual support with handling specific translations. Instead of relying on third-party solutions, it offers first-class tools that integrate smoothly into the framework:
Packages – flutter_localizations and intl provide core support for multiple languages, regional formats, dates, numbers, and currencies
Resource files (.arb) – JSON-like files that store translation strings for each language. They keep translations structured and easy to maintain
Automatic code generation – during build, Dart classes are generated, giving type-safe and convenient access to translations instead of working with raw keys
Integration with MaterialApp – through supportedLocales you define which languages your app supports, and locale determines the active one. This setup ensures that both system locale preferences and user-selected settings can be respected
Together, these features make Flutter’s multilingual support both flexible and scalable. Adding a new language requires only creating an additional .arb file and regenerating the code – no extra manual wiring is needed 🚀.
Implementing Multilingual Support in Flutter
The project will remain simple, but it will clearly demonstrate how localization works in Flutter. We’ll cover not only text translations, but also formatting for dates, times, numbers, and currencies. All changes will happen dynamically – when the user switches the language in the settings, the app will immediately update its interface without requiring a restart.

Setting Up Localization: Packages, Configs, and Resource Files
Let’s begin by adding the necessary packages to the pubspec.yaml:
In addition to these packages, we also need to enable the generate flag, which allows Flutter to automatically generate the localization files. This simplifies accessing translations and ensures that any changes in .arb files are reflected in the app without manual wiring:
flutter:
generate: true
Next, to set up automatic file generation, we need to create an l10n.yaml file at the root of the project. In this file, we’ll define configuration options that control how Flutter generates localization classes from .arb files, such as the directory for resource files, the template language, and other settings.
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-dir: lib/generated/l10n
Now we can create .arb files for the required languages inside the lib/l10n folder. Each file will contain key-value pairs for translations.

The structure of a .arb file is similar to JSON, consisting of key-value pairs where each key represents a text identifier and the value is its translation. For example, an English file might be named app_en.arb:
Here’s an example of a .arb file for German:
After running the application, Flutter automatically generates AppLocalizations files in the /generated folder. These files provide convenient, type-safe access to all translations defined in your .arb files, allowing you to use them directly in your widgets.

Next we can create a L10n class to define the list of supported locales and include additional helper methods. This centralizes locale-related logic, making it easier to manage available languages and perform tasks like retrieving locale names or validating supported locales.
Using Locales in Widgets
With all the setup in place, we can now use our locales in the project. By configuring the locale and supportedLocales properties in MaterialApp, the app will respond to language changes dynamically and display the correct translations and formats throughout the interface.
As we mentioned earlier, to use translated text inside widgets you can simply call the generated AppLocalizations class:
AppLocalizations.of(context).title
At this point, we can already see the magic of translation in action. By default, the app language is English, but if you change the device’s system language to one of the supported locales, the app will automatically switch its interface to the corresponding translation without any additional configuration.
Formatting Dates, Times, and Currency
The intl package provides classes for formatting various types of data according to the current locale. For example, to format dates and times, you can use DateFormat:
DateFormat.yMMMMd(locale).add_jm().format(DateTime.now())


And to format currency, we can use NumberFormat:
NumberFormat.simpleCurrency(locale: locale,).format(10000)


Sometimes you may also need to insert variables into static text, for example when displaying a user’s name, the number of items in a cart, or a formatted date inside a sentence. Flutter localization supports this scenario out of the box – you only need to adjust the values in your .arb files and use placeholders, which will then be replaced dynamically at runtime.
In the code, the usage remains almost the same – the only difference is that you now pass the parameter when calling the localization method. For example:
AppLocalizations.of(context)!.platformVersion(deviceInfo)

Changing locale manually
But not all users stick to their phone’s system language – sometimes they prefer to choose a different one inside the app. Now I’ll show you how to change the language manually.
To use and track locale changes, we’ll rely on the Provider package. It’s a lightweight state management solution that integrates directly with Flutter’s widget tree. With Provider, we can store the current locale in one place and automatically rebuild the UI whenever the language is changed, keeping the implementation clean and reactive.
provider: ^6.1.5+1
Let’s create a LocaleProvider class that will hold the current locale and notify the app when it changes:
LocaleProvider is a ChangeNotifier that stores the current app locale. It initializes with the device language if supported, otherwise falls back to the default locale, and allows updating the locale dynamically with setLocale().
To use our provider throughout the app, we need to wrap the root widget with a ChangeNotifierProvider. This way, the LocaleProvider becomes available anywhere in the widget tree:
To access our provider inside any widget, we can use the following construction:
final provider = Provider.of<LocaleProvider>(context);
And to change the locale in our app, we need to use the locale provided by LocaleProvider inside the MaterialApp:
locale: provider.locale
Now you can design your own language switcher system that best fits your app’s UI and flow. For demonstration purposes, I’ll show how this can be implemented using a simple DropdownButton:
Now everything is in place – we’ve configured localization, added translations, connected a provider for dynamic language switching, and even handled variables in text. The result is a fully functional multilingual Flutter app where both the interface and formatted data (dates, times, numbers, and currency) instantly adapt to the selected language.
Conclusion
Flutter provides everything you need to build truly multilingual applications out of the box. With the help of flutter_localizations and intl, .arb resource files, and automatic code generation, you can easily manage translations and locale-specific data. By adding a simple state management solution like Provider, it becomes possible to switch languages dynamically without restarting the app, giving users full control over their experience.
We’ve seen how to set up localization, format text, dates, times, and currency, and even work with variables inside translations. The final result is a scalable and user-friendly approach that can grow together with your application. Whether you’re building a small demo or a production-ready product, Flutter makes multilingual support straightforward and efficient. 🚀
Full project code is available below 📂
Go Global with Flutter 🌍
At Igniscor, we don’t just build Flutter apps – we craft experiences that speak every user’s language. From dynamic translations to localized dates, times, and currencies, we make sure your product feels natural in any market.
Ready to scale your app worldwide? Let’s bring your idea to life – contact us today! 🚀
Comments