How to translate your Flutter app and edit your .arb files

2021-07-01 Joachim Grill, Andreas Löw, Daniel Sperl Get Sourcecode from GitHub
This is the updated version of the Flutter tutorial. It covers the newest releases of Flutter and the intl package.
The older version is available here

In this tutorial we explain how to quickly set up translations for your Flutter app. The first two sections explain how to set up a simple demo application — feel free to skip it ;-)

We've created this tutorial on a Mac using Flutter's web target. This means that the app will run in Chrome. We assume that it should be easy enough for you to adapt the steps to run on Windows or Linux and/or run the app on an iPhone or Android device. If a platform requires any additional steps, we'll mention them along the way.

Prepare a simple demo project

Install Flutter

git clone https://github.com/flutter/flutter.git
export PATH=$PATH:$(pwd)/flutter/bin

Alternatively Flutter can be downloaded as zip archive from flutter.dev

Create and launch the demo app in Chrome

flutter create myapp
cd myapp
flutter run

Setup internationalization

Add the required dependencies to your project

Add these lines to dependencies: in pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl:

Run flutter pub get packages to download those packages to your project folder.

The other change inside pubspec.yaml is to enable the generate flag. This is added to the section of the pubspec that is specific to Flutter, and is usually located a bit further down in the file.

# The following section is specific to Flutter.
flutter:
  generate: true

Next, import the flutter_localizations library in lib/main.dart and pass localizationsDelegates and supportedLocales to the MaterialApp constructor.

import 'package:flutter_localizations/flutter_localizations.dart';
...

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ...
      localizationsDelegates: [
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate
      ],
      supportedLocales: [
          const Locale('en', ''), // English
          const Locale('de', ''), // German
      ],
      ...

Beware that iOS requires us to specify the supported locales in the Xcode project, as well. So, if you're deploying to iOS, open ios/Runner.xcodeproj with Xcode and add "German" to the Localizations of the project:

How to translate your Flutter application How to translate your Flutter application

flutter run should still compile and run the app successfully. Flutter texts are now localized, but localization of our own texts is still missing.

Set up templates for ARB files

Add a new yaml file to the root directory of the Flutter project called l10n.yaml. Paste the following content:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

This configures where the specific localization files are going to be found.

Let's create that template file, lib/l10n/app_en.arb:

{
    "pushCounterText": "You have pushed the button this many times:"
}

That's the first text we're going to use in our app. Let's add a German translation right away, via the new file lib/l10n/app_de.arb:

{
    "pushCounterText": "Du hast den Button so oft gedrückt:"
}

Now, run your app so that codegen takes place.

flutter run

Of course, the text is still only English (we're not really loading our translation yet) — but you should see a few generated files in .dart_tool/flutter_gen/gen_l10n.

Add localization class

Import the auto-generated class into your code, right at the top of main.dart.

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

Now we need to update the MaterialApp constructor. That new generated class provides two helpers that simplify setting up delegates and locales. Let's make use of that:

return MaterialApp(
  title: 'Flutter Demo',
  localizationsDelegates: AppLocalizations.localizationsDelegates, // <- here
  supportedLocales: AppLocalizations.supportedLocales, // <- and here
  ...

Finally, we can make use of our translated text!

Look for this text widget inside the build-method of MyHomePageState:

Text('You have pushed the button this many times:'),

Replace it with a call to the new AppLocalizations class:

Text(AppLocalizations.of(context)!.pushCounterText);

(Note the !, which means our app is compiled with sound null safety, as is now the default in Dart.)

This code creates a widget that displays the corresponding German or English text. Each key in the arb-file is used as method name of the getter, which means you can comfortably access them via code completion.

Run localized app

Let's give this a test run to see if we were actually successful.

flutter run

This will compile your app and run it inside Chrome. Unless German is your native language, the browser will probably still display the English text. In that case, open a new tab and navigate here: chrome://settings/languages. Add "German" as a language and move it to the top of the list.

Hurray! The Flutter demo will immediately change the text.

Flutter application with English localizations

Flutter application with English localizations

Flutter application with German localizations

Flutter application with German localizations

How to add more translations

To add more translations, you simply edit app_en.arb and app_de.arb, adding new texts along the way, e.g.:

app_en.arb:

{
  "pushCounterText": "You have pushed the button this many times:",
  "appTitle": "Localization Hero"
}

app_de.arb:

{
  "pushCounterText": "Du hast den Button so oft gedrückt:",
  "appTitle": "Mehrsprachen-Held"
}

Then you can use the strings in your application:

// ...
appBar: AppBar(
  title: Text(AppLocalizations.of(context)!.appTitle),
),
// ...

When running the app after adding a new text, your IDE will likely present you with a warning that build errors exist in your project. This is because the AppLocalizations class will need to be re-generated for the appTitle property to be available.

So it's recommended to first add the text resource, then compile your app — and only then start using it. Alternatively, you can ignore the error, as it will be fixed on first run, anyway. For example, in VSCode, you can run the Flutter app by selecting "Debug Anyway" in the build error dialog that appears.

Simplify your translation workflow

Editing the .arb translation files will get a bit cumbersome over the time:

A much simpler workflow is possible if you use BabelEdit:

You can download BabelEdit for Windows, macOS and Linux from here:

Start BabelEdit after the installation and simply drag & drop your project directory into the main window. Click on the Flutter ARB project:

Translate your Flutter application with BabelEdit

BabelEdit now searches the project folder for .arb files and presents them with a guess for the languages contained in the files. Confirm de and en.

Select the language for your flutter translation files

Select your primary language — that is the language that you use in your main translations. It's used as the source language for features like pre-translate. Select en-US by clicking on the configure button:

Select english as source language

BabelEdit now automatically displays suggestions for your translations:

How to pre-translate your .arb files

Finally, save the files using the save button from the toolbar. BabelEdit asks you for the name and location of a .babel file — BabelEdit's project file that contains all project relevant settings.

It also updates your .arb files with the translations.

Did you like the tutorial? Please share!

Source code available for download

The source code is available on GitHub. Clone it using git:

git clone https://github.com/CodeAndWeb/Flutter-Translation-Example.git

or download one of the archives:

Flutter-Translation-Example.zip Flutter-Translation-Example.tar.gz