Making Sense of Angular Internationalization (i18n)

Tsvetomir Tsonev
3 min readApr 10, 2017

--

The Angular approach to i18n is surprisingly complex. Don’t take my word for it, go ahead and read the cookbook.

To recap it for you:

  • Messages are stored in XML files, of all things
  • Modifying the application invalidates existing message files
  • Translations are baked into the application during compilation

At this point I can make an educated guess that it isn’t going to sail everyones boat. Luckily, run-time solutions such as @ngx-translate can do the job as good as ever.

Still, the framework solution has its upsides:

  • There’s no runtime overhead, regardless of the size of your application
  • The XLIFF and XMB file formats are widely recognized in the translator community
  • Tooling support is supposedly good. This includes GUI editors and servers for sharing translations

This will all start to make sense as the applications grows in scale. But before that we need to figure out how to start using the framework on the small scale. We want the banana, but not the Gorilla and the jungle.

Small-scale Localization

Let’s start with what we have. Angular asks from us to extract strings from the application using ng-xi18n every time the application changes. We then have to figure out what changed and update all our existing translations.

What we need is a single source of truth to rely on. Something that won’t be overwritten accidentally by a build script.

This reference storage for the messages can be something as simple as a YAML file, indexed by message key. At this point, you’re thinking…

Well, it turns out there’s already a 14th standard that is supported by the swiss-army knife Translate Toolkit. Hey, don’t blame it on me!

The suggested workflow is:

  • Assign translations an unique, hierarchical key
  • Use the meaning field to “smuggle” our key in the message file
<span i18n="profile.greeting|Greeting for the user in the Profile page">Hello, dear user!</span>
  • Write down translations in a human-writable YAML file.
profile:
# Greeting for the user in the Profile page
greeting: Hello, dear user!
  • Automatically fill message files, using the YAML files

Tooling

The first problem is seeding the YAML files with default translations. The xlf-extract tool can save us a few keystrokes. Given an XLIFF message file, it will populate an YAML file with the messages and their default values.

xlf-extract --lang-file lang/en.yml messages.xlf

The second problem is getting the translations back in the newly generated XLIFF file. The xlf-translate tool takes an YAML file and translate any matching messages in a given XLIFF file.

xlf-translate --lang-file lang/fr.yml messages.fr.xlf

The tool will not overwrite existing translations unless you use the “force” flag. This makes it safe to run xlf-translate on the same XLIFF file multiple times and to modify translations manually.

Building and Deploying

We have our message files all lined up. So far, so good. But we now need to build the application(s) out of them.

Check out the excellent post by Philippe Martin for a primer on how to do that. I’ve forked his sample application to include the tools outlined above.

Does all of this make sense? Let me know what you think in the comments!

--

--