/ angular

Avoiding mojibake with Angular Translate

Yesterday I pushed an update to Meaniscule’s demo site that supports i18n in AngularJS and sports localizations in English and Japanese.

What is i18n, you say? Why, it stands for internationalization. You can read more about i18n and its cousin L10n on Wikipedia.


The Meaniscule demo site is open sourced on GitHub and my hope is that developers interested in i18n for AngularJS can look through the code for ideas on how they might internationalize their web apps.

Be sure to check out the GitHub repo’s readme for more info, but the short story is that the site makes use of angular-translate. Check out their site for a lot of great resources on how to get started.

Pro tip: for hilarity, have Google Chrome translate the Japanese version of the site back into English, as first tried by my Fullstack Teaching Fellow colleague Jimmy Farrell.

Double pro tip: said hilarity is exactly why you don’t want to let Google Translate be the welcome mat for your international users.


So, about avoiding mojibake…

Sanitization strategies may kill your target language

When you implement one of $translateProvider‘s sanitization strategies, your target language might get sanitized right into mojibake. Here is a screenshot of that particular type of fun:

[![I'm sure you can spot the problem, even if you don't read Japanese.](https://blog.ashryan.io/content/images/2015/08/angular-translate-mojibake.png)](https://blog.ashryan.io/content/images/2015/08/angular-translate-mojibake.png)I’m sure you can spot the problem, even if you don’t read Japanese.
#### How can I avoid mojibake?

You will notice that some of the Japanese appears without incident, while some doesn’t. Let’s have a look at the difference in code.

Bad:

<div class="jumbotron">
  <div class="container">
    <h1>{{ 'BRANDING_AND_NAV.TITLE' | translate }}</h1>
    <p>{{ 'BRANDING_AND_NAV.TAG-LINE' | translate }}</p>
  </div>
</div>

Good:

<section id="home">
  <h2 translate="HOME.SECTION-1.HEADING-1"></h2>
  <p translate="HOME.SECTION-1.PAR-1"></p>
  <p translate="HOME.SECTION-1.PAR-2"></p>
  <ul>
    <li translate="HOME.SECTION-1.LI-1"></li>
    <li translate="HOME.SECTION-1.LI-2"></li>
    <li translate="HOME.SECTION-1.LI-3"></li>
  </ul>

  <h2 translate="HOME.SECTION-2.HEADING-1"></h2>
  <p translate="HOME.SECTION-2.PAR-1"></p>
  <p translate="HOME.SECTION-2.PAR-2"></p>
</section>

In other words, standard Angular interpolation (e.g. {{ 'TITLE' | translate }}) can be broken by the sanitizer. But the translate attribute (e.g. <h2 translate="TITLE"></h2>) will be rendered correctly.

So all I have to do is change my jumbotron above to the following code for maximum i18n win:

<div class="jumbotron">
  <div class="container">
    <h1 translate="BRANDING_AND_NAV.TITLE"></h1>
    <p translate="BRANDING_AND_NAV.TAG-LINE"></p>
  </div>
</div>

No more mojibake!