Localization for Dart package

Roman Volkov
3 min readMay 1, 2020

--

When you develop a package you may want to add localization for it. And if you want to use Intl package for localization, you’ll have a problem.

Problem

To do localization with Intl in a common way you should:

  • create a class with localization strings, wrapped in Intl.message();
  • extract the strings for translation from this class to arb files;
  • translate the strings and put them in separate arb files for each language;
  • generate code (messages_*.dart files) based on arb files;
  • define localization delegate (which will be registered in the application) and implement load method, which calls initializeMessages() from generated code and returns an instance of a class from the first paragraph.

This approach is working well in the application, but it has one important limitation: only the first call of initializeMessages() will work as expected. All subsequent calls don’t add strings to localization if there are entries for this locale already.

So if we have several arb files (and messages_*.dart generated for them) that contain different sets of strings for the same locale, only the strings from the first call will be added.

This behavior is good enough in most cases. We don’t need to have multiple files with localization strings. Even if strings are declared in different classes we still can generate a single arb file for all of them. But when I make localization for a package, I want to distribute translations with it, and did not translate the same strings in every application again and again.

One of the solutions may be to generate separate localization classes for each locale and create an appropriate instance in the load method, without calling initializeMessages(). For example this approach is used for localization in the standard flutter_localization package. But I couldn’t find any way to automatically generate such classes in Intl 😞. If you know how to work with such type of localization, — please, leave a comment. I will be grateful for any information.

Thus I want to:

  • localize a package in a familiar, standard way, as well as I do, with an application localization.
  • have the ability to load package localization while using application localization.

Solution

The package multiple_localization was developed to solve this case.

All we need to achieve the desired behavior is to change the localization delegate of load function and remove explicit initializeMessages() call.

Implementing delegate example.

That’s it! Now you can add multiple delegates — translations will be loaded for all of them.

Multiple custom delegates in MaterialApp.

Also you can override translation for a package delegate. Just define an identical get function with the same name in the application localization class (delegate for the application localization should be higher in the list).

⚠️ Important. This approach will work correctly only if the first invoked load() method will be load(), implemented with multiple_localization. Make sure you implement your application localization delegate as described above and add it first to the localizationDelegates list. That’s will be enough.

And that’s all. I hope this article will be useful for you. If you have any questions, corrections or additions — leave your comments, I’ll appreciate any feedback. 👋

--

--

Roman Volkov
Roman Volkov

Responses (1)