DEV Community

Cover image for Flutter Understanding Internationalization and Localization in Flutter
Mouhaned Akermi
Mouhaned Akermi

Posted on

Flutter Understanding Internationalization and Localization in Flutter

In the increasingly globalized world, it’s essential for mobile applications to cater to diverse audiences by supporting multiple languages and regional preferences. This process involves two key concepts: Internationalization (i18n) and Localization (l10n). In this article, we’ll explore what these terms mean, their importance, and how to implement them in a Flutter application.

What is Internationalization (i18n)?
Internationalization refers to the process of designing an application to be easily adaptable to various languages and regions without requiring changes to the codebase. It involves:

Separating Content from Code: All user-facing text, dates, numbers, and other locale-specific data are externalized, typically stored in resource files. This separation allows developers to add or update languages without altering the core application logic.
Supporting Multiple Languages: The application must support switching between different languages and formats. This is typically done by loading different sets of resources based on the user’s locale.
Locale-Specific Formatting: Properly handling formats for dates, numbers, currencies, etc., according to local customs and conventions.

What is Localization (l10n)?
Localization is the process of adapting an application for a specific language or region. It includes:

Translating Text: Converting all user-visible text into the target language(s). This process involves creating and maintaining translation files that contain all the necessary translations.
Adapting Layouts: Adjusting UI elements, such as text fields, buttons, and icons, to accommodate different text lengths and reading directions (e.g., left-to-right or right-to-left).
Cultural Customization: Making culturally appropriate adjustments, such as changing imagery, colors, or symbols, to better resonate with the target audience.

Why Are Internationalization and Localization Important?

1. Broader Reach
By supporting multiple languages and regions, your app can reach a global audience. This not only expands your user base but also enhances user satisfaction by providing a personalized experience.

2. Legal and Cultural Compliance
Different regions have different laws, norms, and cultural sensitivities. Localizing your app ensures that it complies with these local standards and meets the expectations of your users.

3. Competitive Advantage
Offering a localized experience can set your app apart from competitors who may not support multiple languages. This can be a key differentiator, especially in regions where users expect apps to be available in their native language.

Implementing Internationalization and Localization in Flutter
Flutter, Google’s UI toolkit for building natively compiled applications, provides robust support for internationalization and localization. Here’s a step-by-step guide to implementing these features in a Flutter app:

1. Adding Dependencies
First, add the necessary dependencies to your pubspec.yaml file. The most commonly used package for internationalization in Flutter is intl.

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0
Enter fullscreen mode Exit fullscreen mode

2. Defining Supported Locales
In the MaterialApp widget, specify the supported locales and the localization delegates. The delegates are responsible for loading the appropriate translations and formatting rules based on the current locale.

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'l10n/app_localizations.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      supportedLocales: [
        Locale('en', ''), // English
        Locale('es', ''), // Spanish
      ],
      localizationsDelegates: [
        AppLocalizations.delegate, // Custom localization delegate
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      home: MyHomePage(),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Creating Translation Files
For each supported language, create an ARB (Application Resource Bundle) file. These files contain key-value pairs, where the keys are the identifiers used in the code, and the values are the corresponding translations.

Example: intl_en.arb (English)

{
  "appTitle": "My App",
  "helloWorld": "Hello, World!"
}

Enter fullscreen mode Exit fullscreen mode

Example: intl_es.arb (Spanish)

{
  "appTitle": "Mi Aplicación",
  "helloWorld": "¡Hola, Mundo!"
}

Enter fullscreen mode Exit fullscreen mode
  1. Loading and Using Translations Create a custom localization class that extends LocalizationsDelegate and provides methods to load and access the translations. Use this class in your widgets to display localized text.
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class AppLocalizations {
  AppLocalizations(this.locale);

  final Locale locale;

  static AppLocalizations of(BuildContext context) {
    return Localizations.of<AppLocalizations>(context, AppLocalizations);
  }

  static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();

  Map<String, String> _localizedStrings;

  Future<bool> load() async {
    String jsonString = await rootBundle.loadString('lib/l10n/intl_${locale.languageCode}.arb');
    Map<String, dynamic> jsonMap = json.decode(jsonString);

    _localizedStrings = jsonMap.map((key, value) {
      return MapEntry(key, value.toString());
    });

    return true;
  }

  String translate(String key) {
    return _localizedStrings[key];
  }
}

class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
  const _AppLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) {
    return ['en', 'es'].contains(locale.languageCode);
  }

  @override
  Future<AppLocalizations> load(Locale locale) async {
    AppLocalizations localizations = new AppLocalizations(locale);
    await localizations.load();
    return localizations;
  }

  @override
  bool shouldReload(_AppLocalizationsDelegate old) => false;
}`
To use the translations in your widgets:

`@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text(AppLocalizations.of(context).translate('appTitle')),
    ),
    body: Center(
      child: Text(AppLocalizations.of(context).translate('helloWorld')),
    ),
  );
}
Enter fullscreen mode Exit fullscreen mode

5. Testing and Deployment
Ensure that your app is thoroughly tested for each supported language and region. Pay attention to text length, layout issues, and cultural nuances. Once everything is in place, you can deploy your localized app to the respective app stores.

Conclusion
Internationalization and localization are crucial for making your Flutter app accessible and appealing to a global audience. By following best practices and using Flutter’s built-in tools, you can create a seamless and culturally relevant experience for users around the world.

Incorporating i18n and l10n may require an initial investment of time and effort, but the benefits of reaching a broader audience and providing a better user experience make it well worth it. So, take the plunge and make your Flutter app a truly global product!

Thank you ❤️

Top comments (0)