How to Localize Apps Using the Aurelia Framework

Picking up on the discussion about internationalization in JavaScript applications, this tutorial will guide you through the process of performing i18n in AureliaJS. Aurelia is a popular JavaScript framework for web, mobile, and desktop that is broken down into a collection of feature-oriented modules. It boasts very high performance (beating most of the other modern client-side frameworks), ability to build apps with plain JavaScript or TypeScript, as well as many other cool features.

This tutorial will show you how to localize applications using the Aurelia framework, i.e. how to install and configure the aurelia-i18n plugin, where to store translations and how to load them asynchronously. We’ll also discuss how to format your data, add support for HTML translations, switch between locales and observe events. Shall we start?

Creating the App

If you would like to follow along, aurelia-cli will be required, so don’t forget to install it:

Next, create a new application with any name:

I have used a custom setup with the following settings:

  1. RequireJS loader (note that Webpack plays very bad with the I18n plugin at the moment and you might have tough times getting it to work)
  2. Web platform
  3. Babel transpiler
  4. No markup processing
  5. Standard CSS with no pre-processing
  6. No test runners (we are not going to tackle testing in this tutorial, but it is a good idea to do so in the real world)
  7. Atom code editor

Of course, the general approach to localizing Aurelia apps should work with other setups as well, but the code may slightly differ from case to case.

After your dependencies are installed (which may take quite a lot of time), create a new User class. We are going to pretend that our app (for now) works only with an array of some users:

Next, tweak the src/app.js file to require the newly created class and prepare an array of users:

Now we may render them inside the src/app.html:

So far so good: we have some minimalistic app and it is time to proceed to the next section and integrate aurelia-i18n package.

Adding AureliaI18n

Install all the necessary packages by running:

Let me briefly cover what’ve installed:

  • aurelia-i18n is the main star today. It is a plugin that adds internationalization support and does all the heavy lifting for us.
  • i18next is a core plugin that aurelia-i18n relies on. To put it shortly, I18next is an open source internationalization framework used by numerous JavaScript apps out there. If you would like to learn more about vanilla I18next, you may skim through this article.
  • i18next-xhr-backend is an optional but very useful plugin that allows loading translation files in an asynchronous manner from the server.

If you have the same setup as I’ve described in the previous section, tweak the aurelia_project/aurelia.json file by including all the installed plugins into the dependencies section, so that it looks like this:

Note that aurelia-i18n supports other setups as well, including JSPM and Webpack (though, as mentioned above, it is pretty buggy).


Tweak the src/main.js file to incorporate the newly installed plugin:

I’ve pinpointed the lines that should be added to the file. Let’s move step-by-step here:

  1. Import the necessary modules. TCustomAttribute is not really required, but I’ve added it for demonstration purposes.
  2. Import the module to load translations asynchronously.
  3. Hook up the plugin. Be warned that with some setups (for instance, when using Webpack) the plugin’s name should be written as PLATFORM.moduleName('aurelia-i18n'), not just aurelia-i18n as suggested in the docs.
  4. This is an array of aliases that we would like to utilize in order to perform translations. t is the default one, whereas i18n is a custom one.
  5. We specify which backend to use (i18next-xhr-backend in this case).
  6. Our application is going to have support for two languages: English and Russian. On this line, we specify that if translations for the English locale cannot be found, use Russian as a fallback language. Basically, all the settings here are described in the I18next docs.
  7. Here we provide an array of locales to preload translations for. It is very convenient because the corresponding files are loaded in an asynchronous manner and later we don’t need to spend any time loading them once a user changes the site’s language.
  8. That’s a namespace. In general, I18next may support multiple namespaces, but for this demo, a single one will do. We’ll see how this namespace is utilized in a moment.
  9. Here we provide the aliases defined at step #4.
  10. The default language.
  11. Provide debugging information in the browser’s console. Disable this for production apps.
  12. The path where to load translation files from. {{lng}}, of course, means “language” (ru or en), whereas {{ns}} is a namespace. The files must be in JSON format.

Next, what you need to do is create a locales folder in the root of the project (because we’ve specified the ./locales/{{lng}}/{{ns}}.json path in our settings above). Inside that folder create two nested directories named after the locales of your choice (en and ru in this demo). Inside these folders, in turn, create thethe global.json file that is going to host all the translations for the given language. “global” is the name of our namespace defined above. For larger apps, it is quite common to have multiple namespaces and, in turn, multiple files with translations for different sections of the site.

Here  is the content of the en/global.json file:

And ru/translation.jsonfile:

Note here that translation keys can be nested.

Great! The next step is to actually utilize these translations, so proceed to the next section.

Performing Translations in a Simple Way

The simplest way to perform translations is by using an HTML attribute called t (or i18n which is an alias according to our settings). Tweak the src/app.html file like this:

Now run the application using the following command:

Note that the --watch flag must be provided in Windows environment to avoid a pretty nasty bug, preventing the application from opening at all. Next, navigate to http://localhost:9000 and open the browser console. Among other debug messages you should see:

It means that I18next has successfully initialized and loaded all translation files for us. You will also see that both the “Users” and “Name” text is shown on the page which shows that the translations were performed properly.

Controlling Translations Behaviour

By default, translations do not support HTML markup, so if you say something like:

Then the em tag won’t be processed and instead will be printed out in a raw format. To overcome this problem, prepend the translation key with [html] prefix:

Moreover, you may even control how the translation should be added to the given tag. By default, it replaces any text inside, but there are two other prefixes available:

  • [prepend]
  • [append]

Note that these two prefixes implicitly allow HTML content as well.

Formatting the Output

It is possible to easily format numbers and dates with aurelia-i18n. For starters, let’s provide additional information about our users: salary and their birthdate:

Set it in the following way:

And now I would like to format these new values properly. Start with the salary that has to be displayed in a currency format:

nf is a special value converted and here we are saying to format the given number as a currency, prefixed with a euro symbol.

Formatting dates can be done in a similar manner:

You may find more examples of using the plugin in the official docs.

Now let’s proceed to the next feature and add the ability to switch between locales.

Switching Locales

In order to introduce this new feature, I propose creating a separate Locales class. We will need to inject I18N into it:

Also, let’s provide an array of supported locales and store the currently set language:

Now display locales on the page and bind a click event handler to them:

Note that we are also providing a basic styling for a currently selected language using the css attribute. The next step is to process the click event inside the setLocale method:

The idea is simple: we grab the locale’s code and check that it is not the same as the currently set one. If not — use the setLocale method of the i18n object to update locale. Note, by the way, that the i18n object can be used to perform translations programmatically. For example:

The last step is to require these newly created files. First, the template inside the src/app.html file:

Then the module inside the src/app.js:

That’s it! Now try switching between locales — the text on the page should be translated accordingly.

Observing Locale Changes

Sometimes it is desirable to listen for a “locale changed” event and perform specific actions. Let me demonstrate how to do that:

Here are the key points:

  1. We load the BaseI18N module
  2. Also load the EventAggregator
  3. Perform injection of all the necessary modules
  4. Subscribe to a “locale change” event and update all translations inside the current element and all nested elements.
  5. Also update translations as soon as the current class is attached to an element

As you see, nothing complex here!

Bundling Translation Files

What’s interesting, your translation files can be easily packed into the Aurelia bundle. All you need to do is add the .json extension to the extensions section inside the aurelia_project/aurelia.json file:

Learn more here.

Phrase and Translation Files

Working with translation files is hard, especially when the app is big and supports many languages. You might easily miss some translations for a specific language which will lead to user’s confusion. And so Phrase can make your life easier!

Grab your 14-day trial. Phrase supports many different languages and frameworks, including JavaScript of course. It allows to easily import and export translations data. What’s cool, you can quickly understand which translation keys are missing because it’s easy to lose track when working with many languages in big applications. On top of that, you can collaborate with translators as it’s much better to have professionally done localization for your website.


In this article, we have seen how to introduce internationalization into Aurelia applications. We have seen what plugins are required to do that, how to install and setup them. Also, you’ve learned how and where to store the actual translations, how to utilize them and use various formatters. On top of that, we have added the ability to switch between locales and observe the “locale changed” event. Note that aurelia-i18n plugin has other features. Some of them can be found in the docs, whereas others are documented at the website because, after all, Aurelia I18n is powered by this plugin.

Hopefully, you found this article useful! As always, I thank you for staying with me and until the next time.

How to Localize Apps Using the Aurelia Framework
4.9 (97.14%) 7 votes
Ilya Phrase Content Team