Hide chapters

Real-World Flutter by Tutorials

First Edition · Flutter 3.3 · Dart 2.18 · Android Studio or VS Code

Real-World Flutter by Tutorials

Section 1: 16 chapters
Show chapters Hide chapters

9. Internationalizing & Localizing
Written by Edson Bueno

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

At its most basic form, internationalization is the process of removing hard-coded text from your codebase, like Text('Hello'), and replacing it with dynamic properties, like Text(l10n.homeScreenGreetings). The first reason to do that is to have a more organized codebase, and the second is to lay the groundwork for localizing your app.

Localizing means adding support for another language. Spot the distinction between internationalization and localization:

  • Internationalization is the engineering effort of making sure your app is translatable, even if you don’t plan to support more than one language at the moment — or at any moment.
  • Localization is taking advantage of an already internationalized codebase and feeding it the translations it needs to support another language.

But, of course, things can always be more complex. Internationalization and localization often go way beyond just text translation. Different regions write dates differently and can have different phone number formats, addresses, measurement units, currencies, etc. But that’s not for today.

In this chapter, you’ll learn how to:

  • Internationalize your app.
  • Best organize internationalized messages.
  • Localize your app to add support for another language.
  • Approach internationalization and localization in a multi-package codebase.

One quick explanation before you get your feet wet: Internationalization is also referred to as “i18n”. Why? It encompasses the first and last letters of “internationalization” — “i” and “n” — and then substitutes the number “18” for the 18 letters in between — “nternationalizatio”. It’s the same reason people also call localization “l10n”.

Throughout this chapter, you’ll work on the starter project from this chapter’s assets folder.

Getting Started

Use your IDE of choice to open the starter project. Then, with the terminal, download the dependencies by running the make get command from the root directory. Wait for the command to finish executing, then build and run your app. This is what you’ll see:

Note: If you’re having trouble running the app, it’s because you forgot to propagate the configurations you did in the first chapter’s starter project to the following chapters’ materials. If that’s the case, please revisit Chapter 1, “Setting up Your Environment”.

Your app is pretty much complete, except that the only language it supports at the moment is English. Your goal from here on will be to add Portuguese support to it. Why Portuguese? The most populous country that speaks Portuguese is Brazil, which has the third-most app downloads worldwide, and a population where only 5% speaks English. That makes it an excellent target for localization.

Note: You’ll only localize text that’s embedded in the codebase. The quotes themselves, which come from the server, will continue to be English since that’s the only language supported by the API,

Generating Internationalization Files

The first thing to call out is that WonderWords is a multi-package project, where each screen in the app lives in an isolated package:

  sdk: flutter
intl: ^0.17.0

  "signInButtonLabel": "Sign In",
  "signedInUserGreeting": "Hi, {username}!",
  "@signedInUserGreeting": {
    "placeholders": {
      "username": {
        "type": "String"
  "updateProfileTileLabel": "Update Profile",
  "darkModePreferencesHeaderTileLabel": "Dark Mode Preferences",
  "darkModePreferencesAlwaysDarkTileLabel": "Always Dark",
  "darkModePreferencesAlwaysLightTileLabel": "Always Light",
  "darkModePreferencesUseSystemSettingsTileLabel": "Use System Settings",
  "signOutButtonLabel": "Sign Out",
  "signUpOpeningText": "Don't have an account?",
  "signUpButtonLabel": "Sign up"

arb-dir: lib/src/l10n
template-arb-file: messages_en.arb
output-localization-file: profile_menu_localizations.dart
output-class: ProfileMenuLocalizations
nullable-getter: false
synthetic-package: false

Replacing Hard-Coded Text

You have everything you need to start internationalizing your app. Time for the main act.

import 'package:profile_menu/src/l10n/profile_menu_localizations.dart';
final l10n = ProfileMenuLocalizations.of(context);

final l10n = ProfileMenuLocalizations.of(context);

Pluging Localization Classes Into MaterialApp

Now, before running your project, you need to connect that ProfileMenuLocalizations class to the MaterialApp you have on main.dart. The problem is: As of now, ProfileMenuLocalizations is only visible within the profile_menu package, and your MaterialApp lives inside the main package.

export 'src/l10n/profile_menu_localizations.dart';


Adding Portuguese Support

Head back to the profile_menu feature package and expand the lib/src/l10n folder. Create a new file in there named messages_pt.arb.

  "signInButtonLabel": "Entrar",
  "signedInUserGreeting": "Olá, {username}!",
  "@signedInUserGreeting": {
    "placeholders": {
      "username": {
        "type": "String"
  "updateProfileTileLabel": "Atualizar Perfil",
  "darkModePreferencesHeaderTileLabel": "Configurações de Modo Noturno",
  "darkModePreferencesAlwaysDarkTileLabel": "Sempre Escuro",
  "darkModePreferencesAlwaysLightTileLabel": "Sempre Claro",
  "darkModePreferencesUseSystemSettingsTileLabel": "De Acordo com o Sistema",
  "signOutButtonLabel": "Sair",
  "signUpOpeningText": "Não tem uma conta?",
  "signUpButtonLabel": "Cadastrar"

supportedLocales: const [
  Locale('en', ''),
  Locale('pt', ''),

Key Points

  • Internationalization is the process of removing any hard-coded values in your codebase that would need to change if you were to support another language. That can include text images, units, date formats, etc.
  • Localization is the process of adding another language’s translations to the translatable resources you have in an internationalized codebase.
  • Ideally, you should internationalize your projects from the start.
  • Always name your internationalized Strings after the place they appear in your app. The same text can have different translations depending on where it appears.
  • Text internationalization in Flutter is heavily based on code generation. All you have to do is maintain your text in JSON-like files and ask Flutter to parse those files and generate Dart versions of them for you to consume from your code.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now