Angular i18n

Terminology

i18n = Internationalization

l10n = Localization

The number in each is the amount of letters between the start and end.

Why i18n

Whats the point when we have Google Translate?

However

How i18n Generally works

  • The dev codes the app using default text values.

  • The translator receives a file that contains the default values and translates them into the target language.

  • The app then uses this edited version of the file to replace the default values with the translated ones.

Angular Specifics

Multiple Options:

  • Angular's Internal i18n - https://angular.io/guide/i18n

  • ngx-translate - http://www.ngx-translate.com/

AOT vs JIT

JIT: Just In Time (templates and dependencies are evaluated at run time)

AOT: Ahead Of Time (optimized at compile time when you run a production build)

Why AOT:

  • Smaller bundle size
  • Faster startup time
  • More type and error safety

Getting Started

We will go over:

  • Tagging elements for translation
  • Extracting those translations into an XLIFF file
  • Editing an XLIFF file for a new target language
  • Compiling that xliff file into your AOT build

Tagging elements

<a href="google.com" i18n>Go To Google</a>

Attributes

<img alt="Something" i18n-alt src="..." />

Tagging elements (ICU formatting)

<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>
<span i18n>Watch out for {animalType, select, wolf {wolves} cat {kitties} other {animals}}</span>

Extraction

ng xi18n

No CLI?

  • ng-xi18n - a tool that is part of the @angular/compiler repo

  • Webpack Plugin

Editing the XLIFF (Before)

Editing the XLIFF (After)

Tools for Editing XLIFF files

Online Tools:

Applications:

Mostly found via: https://en.wikipedia.org/wiki/XLIFF#Related_tools

Compilation

Build:

ng build --aot --locale fr --i18n-format xlf --i18n-file src/locale/messages.fr.xlf --missing-translation error
--output-path dist/fr

What if your app is served like this https://myapp.com/fr/?

--base-href /fr/

End result (language selection)

Issue: You have a compilation for every language you support. How do you decide which to serve to your user?

Automatic detection is buggy based on browser/os.

Allow the user to choose. (drop-down in header, splash page, etc)

Live coding

Caveats

ICU Attribute Values

<img
  src="..."
  alt="A dynamic image of {{itemCount}} {itemCount, plural, =1 {item} other {items}}"
  i18n-alt
/>

Nesting

<div i18n>Follow this <a href="#">link</a>.</div>

Variable from ts file

<span i18n>{{ someValue }}</span>

Angular i18n Roadmap

i18n Plans Github Issue

Run-time AOT-built i18n

Hacks

Nesting

Instead of:

<div i18n>Follow this <a href="#">link</a>.</div>

Try:

<div><span i18n>Follow this<span> <a href="#" i18n>link</a>.</div>

ICU Formatting in attributes

<div hidden>
  <!-- ICU selection message marked for translation -->
  <span #altValue i18n>{role, select, tinker {Tinker} tailor {Tailor} soldier {Soldier} spy {Spy}} Profile Image
</div>
<img [alt]="removeHtmlComments(altValue.innerHTML)" />

Why removeHtmlComments()?

<span _ngcontent-c4=""><!--bindings={
  "ng-reflect-ng-switch": "tinker"
}--><!--bindings={
  "ng-reflect-ng-switch-case": "tinker"
}-->Tinker<!--bindings={
  "ng-reflect-ng-switch-case": "tailor"
}--><!--bindings={
  "ng-reflect-ng-switch-case": "soldier"
}--><!--bindings={
  "ng-reflect-ng-switch-case": "spy"
}--> Profile Image</span>
removeHtmlComments(html) {
  return html.replace(/<!--[\s\S]*?-->/g, '');
}

Dynamically Created Components

Conference Call Bingo's Hackery

What didn't I cover?

  • Per-route bundles and how that impacts the compilation process?

  • ngx-translate

  • Continuous translation workflows

  • Date/time, number, and currency formatting - Angular pipes can help you with those: https://angular.io/guide/i18n#i18n-pipes

Citations

  • https://angular.io/guide/i18n

  • https://github.com/angular/angular-cli/wiki/stories-internationalization

  • https://github.com/cmgriffing/angular-i18n-presentation/demo

  • https://github.com/cmgriffing/conference-call-bingo