Education
Software Development Executive - II
Last updated onMay 6, 2024
Last updated onJan 9, 2024
In today's globalized world, mobile applications often reach users from various linguistic backgrounds. As developers, we strive to create inclusive and accessible software that speaks to everyone—literally. This is where internationalization, often abbreviated as i18n, comes into play. Internationalization is designing a software application to adapt to various languages and regions without engineering changes. For those of you diving into the world of Flutter, Google's UI toolkit for crafting natively compiled applications, internationalization might initially seem daunting.
But fear not!
In this blog, we'll walk through the basics of Flutter internationalization, making your app world-ready, one locale at a time.
Internationalization, in the context of a Flutter app, involves preparing the app to support multiple languages and regional settings without significant changes to its structure or the need to create separate versions for different locales. It’s a proactive measure to ensure that the app can later be localized, which is translating and adapting the content for specific regions.
Flutter provides tools and libraries that aid in this process, allowing developers to design apps catering to various languages and cultural norms. Through internationalization, we ensure that our Flutter app speaks multiple languages and respects the cultural nuances and preferences that come with them, such as date formats, currency, and text direction.
At the heart of internationalization lies the concept of locale. A locale is a unique identifier, usually composed of a language code and a country code (e.g., en-US for English as used in the United States, or fr-CA for French as used in Canada), which dictates the set of user interface preferences that are to be used to tailor the app experience to the user’s cultural region.
By default, Flutter apps are set to the English locale. Still, they can be configured to support multiple locales, and Flutter excels at detecting and applying the default locale based on the user's system settings. This seamless detection ensures that users worldwide are served with a version of the app that is most appropriate for their system locale.
Widget build buildcontext context isn’t just a string of keywords; it signifies the fundamental structure of a Flutter app's UI, where each widget may need to present a localized value. Flutter's powerful widget system plays a pivotal role in internationalization. Specifically, context objects provide access to the underlying widget tree and the localized resources corresponding to the current locale.
This is where classes like Localizations and Locale come into play, empowering developers to retrieve and apply localized resources right within the build methods of their widgets. In essence, leveraging Flutter's context concept will allow us to pull in the right resources based on the active locale, all within the comforts of the Flutter framework.
With the basics covered, let's dive into setting up your Flutter project for internationalization, configuring translation files, and using widgets to build an app that truly speaks the world's languages. Stay tuned as we prepare to turn this internationalization theory into real-world Flutter practice.
Embarking on the road to Flutter internationalization requires some initial groundwork. Here's how to lay the foundation for a multilingual Flutter project.
Before starting the internationalization process, you must ensure your Flutter project is structured correctly. Internationalization calls for an organized approach where code, assets, and localization files are easily managed.
The **pubspec.yaml** file is the configuration and declaration file for Flutter projects. This is where you will specify the necessary dependencies and assets for internationalization.
Open your pubspec.yaml file is found in your Flutter project's root directory.
Add the flutter_localizations package provided by the Flutter team, which includes essential tools and classes for internationalization. Ensure you have this under the dependencies section as shown below:
1dependencies: 2 flutter: 3 sdk: flutter 4 flutter_localizations: ^0.2.0 5
Also, specify the list of locales your app will support under the flutter section:
1flutter: 2 uses-material-design: true 3 supported-locales: 4 - en 5 - es 6 - fr 7 - ja 8
With these configurations, you are signaling to your Flutter app which languages it should be prepared to support.
Flutter utilizes the ARB (Application Resource Bundle) format to define local key-value pairs. These arb files serve as templates from which localization files will be generated.
Create a new arb file named intl_en.arb for your default English locale with necessary key-value pairs. This file will act as the template arb file.
Place this file in the l10n folder within your Flutter project.
1{ 2 "@@locale": "en", 3 "title": "Welcome", 4 "@title": { 5 "description": "Title for the Demo App", 6 "type": "text", 7 "placeholders": {} 8 } 9} 10
Creating a template arb file like this is the first step in providing localized content for your Flutter apps. By defining a default locale and using ARB as a template, you can ensure a consistent and maintainable strategy for internationalization.
Understanding and managing locales is paramount to Flutter internationalization. Here, we'll outline how to handle language settings and user preferences within your Flutter app.
In internationalization, setting up your default locale is just the start. Flutter also needs to know the specific locales your app intends to support.
Defining a default locale ensures users have a fallback language regardless of their device's locale. This is critical because it guarantees that your app remains usable even if it doesn't support the user's preferred language.
Flutter apps define supported locales through the supportedLocales property in the MaterialApp or CupertinoApp widget. This list informs Flutter which locales your app explicitly supports and can handle.
1MaterialApp( 2 // ... 3 supportedLocales: [ 4 const Locale('en', 'US'), 5 const Locale('es', 'ES'), 6 const Locale('fr', 'FR'), 7 // Add other locales your app supports 8 ], 9 // ... 10); 11
To produce a localized Flutter app, you must be mindful of the **BuildContext** when building widgets. Internationalization in widgets requires context to determine which localized strings are displayed.
The BuildContext provides access to the current Locale through the Localizations widget. The widget utilizes the current locale to fetch the correct localized values.
For example, when building a Text widget, you can use Localizations to render a string in the current locale:
1Text(Localizations.of<YourLocalizationClass>(context, YourLocalizationClass).title) 2
Some users prefer to retain their chosen app language even when the system locale changes. Implementing features that allow users to select and save their preferred app language is essential, overriding the system locale if necessary.
1Locale myLocale = Locale('en', 'US'); // A user preferred locale 2MaterialApp( 3 locale: myLocale, 4 //... 5); 6
Flutter has the inherent ability to detect and adapt to the device locale. Using the device's locale, your Flutter app can automatically switch to the appropriate language, provided that the language is among the supported locales.
If no explicit locale is provided, Flutter will use the system locale, which ensures your app matches the language settings of the user's device.
To enhance this behavior, implement a localeListResolutionCallback, which can further customize the locale selection process based on the list of preferred locales obtained from the device:
1MaterialApp( 2 // ... 3 localeListResolutionCallback: (locales, supportedLocales) { 4 // Determine the locale here based on user preferences or app logic 5 }, 6 // ... 7); 8
Having configured your Flutter app for internationalization, let's learn how to implement those configurations and build a localizable user interface.
Flutter's widget-centric design makes it easier to put internationalization into practice. Widgets are the fundamental building blocks in a Flutter app, and they are reconstructed with varying properties when building the UI.
When a widget is being built, it has access to a BuildContext, which provides the localized resources for the current locale of the app. Each time the locale changes, the widgets can quickly rebuild to reflect the new language selections using the setState method or by responding to notifications of locale changes.
1Widget build(BuildContext context) { 2 var localizedTitle = Localizations.of<YourLocalizationsClass>(context, YourLocalizationsClass).title; 3 return AppBar( 4 title: Text(localizedTitle), 5 ); 6} 7
This snippet demonstrates how a widget uses BuildContext to obtain a localized string for its title. Notice how buildcontext is instrumental in fetching the right translation.
To keep your code clean and maintainable, you can encapsulate localization within a stateless widget, allowing you to reuse localized widgets across your app.
Here’s an example where we extend a **StatelessWidget** to create a localized app:
1class LocalizedApp extends StatelessWidget { 2 Widget build(BuildContext context) { 3 var localizedGreeting = Localizations.of<YourLocalizationsClass>(context, YourLocalizationsClass).greeting; 4 5 return MaterialApp( 6 home: Scaffold( 7 appBar: AppBar( 8 title: Text(localizedGreeting), 9 ), 10 // Other widgets go here... 11 ), 12 ); 13 } 14} 15
In this code, the LocalizedApp uses Localizations.of to access the translations. The StatelessWidget.build method is a prime location for implementing localization since it will be called again upon locale changes, ensuring the UI stays in sync with the targeted locale.
Flutter's Localizations widget is designed to load and look up localized values based on the current locale. It automatically provides localized resources for Flutter widgets as well.
In the UI, when a standard Flutter widget, like a Text widget, requires text, that string is fetched from the correct localization file depending on the active locale:
1Text(Localizations.of<AppLocalizations>(context, AppLocalizations).welcomeText) 2
This Text widget will correctly display a 'welcome' message that varies based on the current locale, providing a highly customizable experience to users in their native language.
Utilizing buildcontext context, statelesswidget, and the Localizations widget effectively primes your Flutter app for a global stage. Now, we'll generate the output localization files resulting from the aforementioned localization settings and techniques, readying your Flutter app for deployment to multilingual users.
Once you have structured your localization files and written the code to use these resources, the next phase is generating the file that holds all the localized strings for different locales. This is essential for integrating the localized content into your Flutter application's runtime.
Flutter provides the gen_l10n tool to automate the creation of localization files from the ARB templates you've prepared.
Here’s how you can utilize the gen_l10n tool within your Flutter project:
Add configurations for the gen_l10n tool in the pubspec.yaml file to define the input and output directory for the localization files as well as the ARB directory (arb dir):
1flutter: 2 generate: true 3 # ... other configurations ... 4 5 # Localization configuration 6 gen_l10n: 7 arb-dir: lib/l10n 8 output-localization-file: app_localizations.dart 9
Upon running the Flutter build command, the gen_l10n tool will read through your ARB files in the specified directory and generate a corresponding Dart file for each locale.
You may also include additional configurations for locales, messages, and placeholders that require customization:
1flutter: 2 # ... previous content ... 3 4 gen_l10n: 5 arb-dir: lib/l10n 6 output-localization-file: app_localizations.dart 7 template-arb-file: intl_en.arb 8 synthetic-package: false 9 fallback-locale: 'en' 10 include-if-null: false 11 // Add more configurations as needed ... 12
After generating the localization files, it's a good practice to review them to ensure that:
The generated output localization file will usually be placed in the .dart_tool/flutter_gen/gen_l10n/ directory, under the name specified in the config (e.g., app_localizations.dart). Review this file to ensure the generated classes and methods align with your expectations.
With the localization Dart files in place, the foundation for internationalization is complete. Your Flutter app can now present content in different languages, as defined by your ARB templates.
With your Flutter app's localization infrastructure set up, it's time to focus on the heart of internationalization—translation files. These files contain the actual text that will be displayed in different languages within your app.
To support a variety of languages, your Flutter app will require separate translation files for each language, each with proper internationalization keys and the corresponding translated strings.
Each language your app supports will have its own ARB file in your designated ARB directory (commonly lib/l10n). The file names should include the language code and, optionally, the country code (e.g., intl_es.arb for Spanish, intl_fr.arb for French).
1{ 2 "@@locale": "es", 3 "title": "Bienvenido", 4 "@title": { 5 "description": "Título para la aplicación de demostración", 6 "type": "text", 7 "placeholders": {} 8 } 9} 10
When you need to add support for a new language or locale, create a new ARB file following the naming convention, and provide translations for all the key-value pairs found in the template ARB file. Remember to update the supportedLocales list in your main app widget to include the new locale.
Ensure each ARB file contains the same keys; otherwise, you'll face missing translation issues when switching between languages. The values will be language-specific, but the keys must match across all translation files.
Localization often involves using placeholders within strings to inject dynamic content, such as user names, dates, or numbers.
Placeholders are defined within your ARB files and can represent a value that changes based on the user or context.
1{ 2 "greetingMessage": "Hello, {username}!", 3 "@greetingMessage": { 4 "description": "Greeting message with a username", 5 "placeholders": { 6 "username": {} 7 } 8 } 9} 10
Pay particular attention to formatting settings in your translation files for dates, times, and numbers. Consistency in these areas is essential, especially since different languages might follow different rules for displaying such localized values.
As we tie together the insights and strategies expounded in this guide, it's evident that Flutter's internationalization is an invaluable feature for any app looking to make a mark on the global stage. By following the steps we've outlined—from setting up your project for internationalization to leveraging translation files and best practices—you're now empowered to create Flutter apps that resonate with users across any locale.
Flutter's robust framework and its suite of localization tools have demonstrated their capability to simplify what otherwise could be a challenging task. Building and managing an app that speaks multiple languages is no longer a Herculean effort but an achievable goal for developers.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.