Wednesday, 29 July 2015

AngularJS and localisation/internationalisation with angular-translate

I have just battled to get translation working. I was trying to follow http://www.ng-newsletter.com/posts/angular-translate.html which seems ok. However there were multiple issues along the way, so I thought I would detail them here.

Initial Setup

Just add the following as a dependency to the angular app

 'pascalprecht.translate'

You will also need to include a reference to angular-translate.min.js.

Sanitize

When you run the app, the library shows a warning that you should set a sanitise option. To do this, you need to add another dependency to the angular app

 'ngSanitize'

You will also need to include a reference to angular-santize.min.js if you don't already have one.

You then need to add this line to configure the strategy

 $translateProvider.useSanitizeValueStrategy('sanitize');

Async page load

For async page loads, you need to add a reference to angular-translate-loader-static-files.min.js. You can use this config

 $translateProvider.useStaticFilesLoader({
    prefix: 'i18n/locale-',
    suffix: '.json'
 });

Error On Load

I followed the samples, and when the async load occurred, the async load/parse failed with the following error.

 Unexpected token '

The secret is to make sure both keys and values are enclosed in quotes.

 {
   "TITLE": "Hallo",
   "FOO": "Dies ist ein Paragraph.",
   "BUTTON_LANG_EN": "englisch",
   "BUTTON_LANG_DE": "deutsch"
 }

JSON requires this. I did find someone else that hit the same problem, so I guess it is not just me.

Stopping Page Flicker

When you load the translations async, the page first shows with the keys, and then updates to show the actual translations. If you search, everyone says "just use translate-cloak". They neglect to actually tell you how.

Body Tag

I added the translate-cloak directive to my body. I also added the translate-cloak css class. The directive ensures that the class is removed when the page has loaded. The css means that as the page loads, it is initially hidden

 translate-cloak class="translate-cloak"

CSS

I couldn't find anyone mention it, but you actually need to hide the css style translate-cloak. So I added the following to the css

 .translate-cloak {
    visibility: hidden;
 }