@title
Internationalization (i18n)
@intro
Translate the app's template text into multiple languages.
@description
{@a top}
Angular's _internationalization_ (_i18n_) tools help make your app available in multiple languages.
## Table of contents
* [Angular and i18n template translation](guide/i18n#angular-i18n)
* [Mark text with the _i18n_ attribute](guide/i18n#i18n-attribute)
* [Add _i18n-..._ translation attributes](guide/i18n#translate-attributes)
* [Handle singular and plural](guide/i18n#cardinality)
* [Select among alternative texts](guide/i18n#select)
* [Create a translation source file with the **_ng-xi18n_ extraction tool**](guide/i18n#ng-xi18n)
* [Translate text messages](guide/i18n#translate)
* [Merge the completed translation file into the app](guide/i18n#merge)
* [Merge with the JIT compiler](guide/i18n#jit)
* [Internationalization with the AOT compiler](guide/i18n#aot)
* [Translation file maintenance and _id_ changes](guide/i18n#maintenance)
**Try this** live example
of a JIT-compiled app, translated into Spanish.
{@a angular-i18n}
## Angular and _i18n_ template translation
Application internationalization is a challenging, many-faceted effort that
takes dedication and enduring commitment.
Angular's _i18n_ internationalization facilities can help.
This page describes the _i18n_ tools available to assist translation of component template text
into multiple languages.
Practitioners of _internationalization_ refer to a translatable text as a "_message_".
This page uses the words "_text_" and "_message_" interchangably and in the combination, "_text message_".
The _i18n_ template translation process has four phases:
1. Mark static text messages in your component templates for translation.
1. An angular _i18n_ tool extracts the marked messages into an industry standard translation source file.
1. A translator edits that file, translating the extracted text messages into the target language,
and returns the file to you.
1. The Angular compiler imports the completed translation files,
replaces the original messages with translated text, and generates a new version of the application
in the target language.
You need to build and deploy a separate version of the application for each supported language.
{@a i18n-attribute}
## Mark text with the _i18n_ attribute
The Angular `i18n` attribute is a marker for translatable content.
Place it on every element tag whose fixed text should be translated.
~~~ {.alert.is-helpful}
`i18n` is not an Angular _directive_.
It's a custom _attribute_, recognized by Angular tools and compilers.
After translation, the compiler removes it.
~~~
In the accompanying sample, an `
` tag displays a simple English language greeting
that you translate into Spanish:
{@example 'cb-i18n/ts/src/app/app.component.1.html' region='greeting'}
Add the `i18n` attribute to the tag to mark it for translation.
{@example 'cb-i18n/ts/src/app/app.component.1.html' region='i18n-attribute'}
### Help the translator with a _description_ and _intent_
In order to translate it accurately, the translator may
need a description of the message.
Assign a description to the i18n attribute:
{@example 'cb-i18n/ts/src/app/app.component.1.html' region='i18n-attribute-desc'}
In order to deliver a correct translation, the translator may need to
know your _intent_—the true _meaning_ of the text
within _this particular_ application context.
In front of the description, add some contextual meaning to the assigned string,
separating it from the description with the `|` character (`|`):
{@example 'cb-i18n/ts/src/app/app.component.html' region='i18n-attribute-meaning'}
While all appearances of a message with the _same_ meaning have the _same_ translation,
a message with *a variety of possible meanings* could have different translations.
The Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file
to facilitiate contextually-specific translations.
### Translate text without creating an element
Suppose there is a stretch of text that you'd like to translate.
You could wrap it in a `` tag but for some reason (CSS comes to mind)
you don't want to create a new DOM element merely to facilitate translation.
Here are two techniques to try.
(1) Wrap the text in an `` element. The `` is never renderered:
{@example 'cb-i18n/ts/src/app/app.component.html' region='i18n-ng-container'}
(2) Wrap the text in a pair of HTML comments:
{@example 'cb-i18n/ts/src/app/app.component.html' region='i18n-with-comment'}
{@a translate-attributes}
## Add _i18n-..._ translation attributes
You've added an image to your template. You care about accessibility too so you add a `title` attribute:
{@example 'cb-i18n/ts/src/app/app.component.1.html' region='i18n-title'}
The `title` attribute needs to be translated.
Angular i18n support has more translation attributes in the form,`i18n-x`, where `x` is the
name of the attribute to translate.
To translate the `title` on the `img` tag from the previous example, write:
{@example 'cb-i18n/ts/src/app/app.component.html' region='i18n-title-translate'}
You can also assign a meaning and a description with the `i18n-x="|"` syntax.
{@a cardinality}
## Handle singular and plural
Different languages have different pluralization rules.
Suppose your application says something about a collection of wolves.
In English, depending upon the number of wolves, you could display "no wolves", "one wolf", "two wolves", or "a wolf pack".
Other languages might express the _cardinality_ differently.
Here's how you could mark up the component template to display the phrase appropriate to the number of wolves:
{@example 'cb-i18n/ts/src/app/app.component.html' region='i18n-plural'}
* The first parameter is the key. It is bound to the component property (`wolves`)
that determines the number of wolves.
* The second parameter identifies this as a `plural` translation type.
* The third parameter defines a pluralization pattern consisting of pluralization
categories and their matching values.
Pluralization categories include:
* =0
* =1
* =5
* few
* other
Put the default _English_ translation in braces (`{}`) next to the pluralization category.
* When you're talking about one wolf, you could write `=1 {one wolf}`.
* For zero wolves, you could write `=0 {no wolves}`.
* For two wolves, you could write `=2 {two wolves}`.
You could keep this up for three, four, and every other number of wolves.
Or you could specify the **`other`** category as a catch-all for any unmatched cardinality
and write something like: `other {a wolf pack}`.
This syntax conforms to the
ICU Message Format
that derives from the
Common Locale Data Repository (CLDR),
which specifies the
pluralization rules.
{@a select}
## Select among alternative texts
The application displays different text depending upon whether the hero is male or female.
These text alternatives require translation too.
You can handle this with a `select` translation.
A `select` also follows the
ICU message syntax.
You choose among alternative translation based on a string value instead of a number.
The following format message in the component template binds to the component's `gender`
property, which outputs either an "m" or an "f".
The message maps those values to the appropriate translation:
{@example 'cb-i18n/ts/src/app/app.component.html' region='i18n-select'}
{@a ng-xi18n}
## Create a translation source file with the _ng-xi18n_ tool
Use the **_ng-xi18n_ extraction tool** to extract the `i18n`-marked texts
into a translation source file in an industry standard format.
This is an Angular CLI tool in the `@angular/compiler-cli` npm package.
If you haven't already installed the CLI and its `platform-server` peer dependency, do so now:
npm install @angular/compiler-cli @angular/platform-server --save
Open a terminal window at the root of the application project and enter the `ng-xi18n` command:
./node_modules/.bin/ng-xi18n
Windows users may have to quote the command like this: `"./node_modules/.bin/ng-xi18n"`
By default, the tool generates a translation file named **`messages.xlf`** in the
XML Localisation Interchange File Format (XLIFF, version 1.2).
{@a other-formats}
### Other translation formats
You can generate a file named **`messages.xmb`** in the
XML Message Bundle (XMB) format
by adding the `--i18nFormat=xmb` flag.
./node_modules/.bin/ng-xi18n --i18nFormat=xmb
This sample sticks with the _XLIFF_ format.
{@a ng-xi18n-options}
### Other options
You may have to specify additional options.
For example, if the `tsconfig.json` TypeScript configuration
file is located somewhere other than in the root folder,
you must identify the path to it with the `-p` option:
./node_modules/.bin/ng-xi18n -p path/to/tsconfig.json
./node_modules/.bin/ng-xi18n --i18nFormat=xmb -p path/to/tsconfig.json
{@a npm-i18n-script}
### Add an _npm_ script for convenience
Consider adding a convenience shortcut to the `scripts` section of the `package.json`
to make the command easier to remember and run:
"scripts": {
"i18n": "ng-xi18n",
...
}
Now you can issue command variations such as these:
npm run i18n
npm run i18n -- -p path/to/tsconfig.json
npm run i18n -- --i18nFormat=xmb -p path/to/tsconfig.json
Note the `--` flag before the options.
It tells _npm_ to pass every flag thereafter to `ng-xi18n`.
{@a translate}
## Translate text messages
The `ng-xi18n` command generates a translation source file
in the project root folder named `messages.xlf`.
The next step is to translate the English language template
text into the specific language translation
files. The cookbook sample creates a Spanish translation file.
{@a localization-folder}
### Create a localization folder
You will probably translate into more than one other language so it's a good idea
for the project structure to reflect your entire internationalization effort.
One approach is to dedicate a folder to localization and store related assets
(for example, internationalization files) there.
Localization and internationalization are
different but closely related terms.This cookbook follows that suggestion. It has a `locale` folder under the `src/`.
Assets within the folder carry a filename extension that matches a language-culture code from a
well-known codeset.
Make a copy of the `messages.xlf` file, put it in the `locale` folder and
rename it `messages.es.xlf`for the Spanish language translation.
Do the same for each target language.
### Translate text nodes
In the real world, you send the `messages.es.xlf` file to a Spanish translator who fills in the translations
using one of the
many XLIFF file editors.
This sample file is easy to translate without a special editor or knowledge of Spanish.
Open `messages.es.xlf` and find the first `` section:
{@example 'cb-i18n/ts/src/locale/messages.es.xlf.html' region='translated-hello'}
This XML element represents the translation of the `
` greeting tag you marked with the `i18n` attribute.
Using the _source_, _description_, and _meaning_ elements to guide your translation,
replace the `` tag with the Spanish greeting:
{@example 'cb-i18n/ts/src/locale/messages.es.xlf.html' region='translated-hello'}
~~~ {.alert.is-important}
Note that the tool generates the `id`. **Don't touch it.**
Its value depends on the content of the message and its assigned meaning.
Change either factor and the `id` changes as well.
See the **[translation file maintenance discussion](guide/i18n#maintenance)**.
~~~
Translate the other text nodes the same way:
{@example 'cb-i18n/ts/src/locale/messages.es.xlf.html' region='translated-other-nodes'}
{@a translate-plural-select}
## Translate _plural_ and _select_
Translating _plural_ and _select_ messages is a little tricky.
The `