DEV Community

Cover image for How to i18n in Flutter?
Pedro Massango
Pedro Massango

Posted on • Updated on

How to i18n in Flutter?

UPDATE:

The plugin used in this article was deprecated, Use it at your own risk.

After some months (maybe a year) working with Flutter I want to start sharing advanced things about Flutter like state management, i18n and more. Also checkout my Youtube channel for videos about Flutter.

In this post we will discus about i18n and see two options to handle i18n in our projects.

What is i18n?

Is a shorthand for internationalization. The came because the internationalization word have twenty letters and between the first letter (i) and the last(n) there are eighteen letters.

Internationalization means making our app available in other language, country or locale.

How do we setup i18n in Flutter?

I know two ways to do i18n in Flutter, just keep reading…

1. The common way: manually

Here maybe you want to pause my post and take a look to the Flutter documentation, to get some background. Basically you will need to:

  1. Create a single-source class that will have your stringsThe class that you will use to access your strings. It uses the Intl package to pick your strings or you can choose your own approach.
  2. Create a class for each supported locale by your app 😔
    You also need to create a single file for each locale supported by your app. Each file will have texts localized for that locale.
  3. Configure your MaterialApp with localizationsDelegates to point your custom localization delegates (this allow you to access the strings).

The you will use something like that to access your strings:

MyLocalizations.of(context).appDescription

What is wrong with this method?

Nothing wrong here, we just have some negative points…

  • Hard to set it up. You must create the classes containing your translated strings.
  • Hard to translate your strings😪.
  • Each time you want to add a new string you will need to add it in each locale’s strings file😔.
  • IntelliJ can not tell you whether your strings key already exists or it is wrong, and you can get runtime error (or even crash).

This is great for small projects (maybe not). If you have a big project that support, lets say, more than two locales you will need to create files for each locale and add the strings manually. It will be very hard to translate your strings.

2. Automated way: Flutter i18n plugin

Let me introduce to you the Flutter i18n Plugin for IntelliJ IDEA created by Razvan Lung. A plugin that simplify i18n managment in your project.

What are the advantages of this plugin over the default implementation?

  • Easy implementation;
  • Easy to translate your strings because it uses .arb files;
  • IntelliJ will let you know wether your string’s key is wrong or duplicated at develompent time.

.arb (Android Resources Bundle) are files supported by the Intl Dart’s package, also supporteb by the Google translator toolkit. Each locale have it own .arb file containing JSON table with strings for that locale.

How do I set it up?

  1. Getting the plugin
    On IntelliJ IDEA go to Settings > Plugins and search for Flutter i18n and click on install. Once the download completes restart your IDE.
2. The next step is to update our MaterialApp widget and add the generated localization delegate to give us the the access of our strings over all of our widgets and the generated supported locales list that is basically contains the locale code of each generated .arb locale’s file.
class MyApp extends StatelessWidget {

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
localizationsDelegates: [S.delegate],
supportedLocales: S.delegate.supportedLocales,
//localeResolutionCallback: ,
home: HomePage(),
);
}
}

The plugin generate a class called S this is the class that you use to get your strings providing the context into it. You get your strings by calling: S.of(context).yourStringKey.

Note: we also have the option to register a resolution callback (the callback called if user select an unsupported locale), here we basicaly should choose wich locale will be the default in case of an unsupported locale get selected. If we do not provide a resolution callback the plugin will choose the first supported locale or we can provide a custom one…

// use English as the default locale
localeResolutionCallback: S.delegate.resolution(fallback: Locale('en'))

Adding new arb files manually

The plugin create a default .arb file for English. To add a new arb file right click on root-project/res folder and select New -> Arb File. Then pick your language from the list, and region if necessary.Your arb files are located at “root-project/res/values/”.

1. Referencing the values

The arb JSON table’s keys, become a valid Dart variable names. They correspond to methods from the S class. For example:

S.of(context).how_to_play

Those Dart variable names are also generated when you extract a string. In case the user change the device language the (S) class automatically load values for the new locale (You don’t need to restart).

Adding new .arb files and register the strings automatically

To create the .arb file for Portuguese for example, you can just got to a string and press Alt+Enter you have the option to automatically internationalize that string. And if the arb file for that locale does not exist, you can easylly creat it. See with your own eyes…

Easily extract strings to yours .arb files

Now that you have .arb files you can use tools like Google Translator Toolkit to translate your files automatically. Don’t waste your time by making i18n manually. 😎

Read more about the plugin in the official page.

That is it for now. Hope you had a nice read. Share and leave your thoughts below in comments. And don’t forget to leave your votes. See you next time.

Top comments (12)

Collapse
 
marcossevilla profile image
Marcos Sevilla

This plugin is deprecated now (plugins.jetbrains.com/plugin/10128...).

These are the new alternatives:

Hope this is helpful and thanks to Pedro for the hack!

Collapse
 
victoriavhe profile image
victoria h. edon

Hi Pedro, could you specify what Flutter version that you used?
I tried to use it exactly as your tutorial on Flutter 1.12.13+hotfix.8 and it doesn't work. It always returns null. I've run flutter doctor and there was no issues found.

Collapse
 
pedromassango profile image
Pedro Massango

Hi @victoria

I'm using the same version as you (1.12.13+hotfix.8). Can I see your MaterialApp configuration? Maybe you are missing something there.

Sorry for the late repply

Collapse
 
bryanmuloni profile image
Sirikye Brian

Hi Pedro, thank you for the article. My question is if this approach can be blended with Sharedpreferences and Provider for keeping track of a given locale and state management.

Collapse
 
pedromassango profile image
Pedro Massango

Yes and this approach already update your app if the user change the device's language

Collapse
 
bryanmuloni profile image
Sirikye Brian

Okay, how possible can I incorporate those. Is it allowed to update the generated files.
If possible show me a basic implementation.
Thank you.

Thread Thread
 
pedromassango profile image
Pedro Massango

The plugin was deprecated, please find another way to localize your app. Read more in the plugin's page

Thread Thread
 
bryanmuloni profile image
Sirikye Brian

Exactly that's what I saw while reading about the plugin here: plugins.jetbrains.com/plugin/10128...
Thank you.

Collapse
 
hdimessi profile image
Hussein Dimessi

Hi Pedro,
Thanks for the post, but I have a small issue with the plugin, the extract feature doesnt work, it doesnt actually add the key-value to the arb files, each time I have to do it manually, do you have any thoughts about what could be wrong ?

Collapse
 
kminakovsky profile image
Кирилл Минаковский

Just for you know, .abr isn't 'Android Bundle Resource.'
github.com/google/app-resource-bun...
Btw, thx for the article.

Collapse
 
minhvuongrbs profile image
minhvuongrbs

Do we have the command to use it in other IDE like VSCode?

Collapse
 
pedromassango profile image
Pedro Massango

Yes we have.