top of page

Multilingual Support in Flutter: From Setup to Implementation

  • Oct 16, 2025
  • 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.


cover image

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.


final result gif

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.


files structure in l10n folder

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.


structure of generated folder

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())
date and time on German
date and time on English

And to format currency, we can use NumberFormat:

NumberFormat.simpleCurrency(locale: locale,).format(10000)
currency on english
currency on german

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)
text with variable

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


Recent Posts

Leave us a message and we'll get back to you

Our Location

Warszawska 6, lok. 32

Bialystok, Poland

Message was sent! Thanks

Send us your request
bottom of page