diff --git a/aio/content/examples/i18n/doc-files/app.locale_data.ts b/aio/content/examples/i18n/doc-files/app.locale_data.ts
index b7d637489f..05c83be034 100644
--- a/aio/content/examples/i18n/doc-files/app.locale_data.ts
+++ b/aio/content/examples/i18n/doc-files/app.locale_data.ts
@@ -2,5 +2,6 @@
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
-registerLocaleData(localeFr);
+// the second parameter 'fr' is optional
+registerLocaleData(localeFr, 'fr');
// #enddocregion import-locale
diff --git a/aio/content/examples/i18n/doc-files/app.locale_data_extra.ts b/aio/content/examples/i18n/doc-files/app.locale_data_extra.ts
index 69e637d6a7..05b7b80d53 100644
--- a/aio/content/examples/i18n/doc-files/app.locale_data_extra.ts
+++ b/aio/content/examples/i18n/doc-files/app.locale_data_extra.ts
@@ -1,7 +1,7 @@
// #docregion import-locale-extra
import { registerLocaleData } from '@angular/common';
-import localeFrCa from '@angular/common/locales/fr-CA';
-import localeFrCaExtra from '@angular/common/locales/extra/fr-CA';
+import localeFr from '@angular/common/locales/fr';
+import localeFrExtra from '@angular/common/locales/extra/fr';
-registerLocaleData(localeFrCa, localeFrCaExtra);
+registerLocaleData(localeFr, 'fr-FR', localeFrExtra);
// #enddocregion import-locale-extra
diff --git a/aio/content/guide/i18n.md b/aio/content/guide/i18n.md
index d046aec5c6..aea41cff3f 100644
--- a/aio/content/guide/i18n.md
+++ b/aio/content/guide/i18n.md
@@ -8,7 +8,6 @@ See the i18n Example for a
an AOT-compiled app, translated into French.
{@a angular-i18n}
-
## Angular and i18n
Angular simplifies the following aspects of internationalization:
@@ -62,6 +61,23 @@ For more information about Unicode locale identifiers, see the
For a complete list of locales supported by Angular, see
[the Angular repository](https://github.com/angular/angular/tree/master/packages/common/locales).
+The locale identifiers used by CLDR and Angular are based on [BCP47](http://www.rfc-editor.org/rfc/bcp/bcp47.txt).
+These specifications change over time; the following table maps previous identifiers to current ones at
+time of writing:
+
+| Locale name | Old locale id | New locale id |
+|-------------------------------|-------------------|---------------|
+| Indonesian | in | id |
+| Hebrew | iw | he |
+| Romanian Moldova | mo | ro-MD |
+| Norwegian Bokmål | no, no-NO | nb |
+| Serbian Latin | sh | sr-Latn |
+| Filipino | tl | fil |
+| Portuguese Brazil | pt-BR | pt |
+| Chinese Simplified | zh-cn, zh-Hans-CN | zh-Hans |
+| Chinese Traditional | zh-tw, zh-Hant-TW | zh-Hant |
+| Chinese Traditional Hong Kong | zh-hk | zh-Hant-HK |
+
## i18n pipes
@@ -78,6 +94,14 @@ If you want to import locale data for other languages, you can do it manually:
+The first parameter is an object containing the locale data imported from `@angular/common/locales`.
+By default, the imported locale data is registered with the locale id that is defined in the Angular
+locale data itself.
+If you want to register the imported locale data with another locale id, use the second parameter to
+specify a custom locale id. For example, Angular's locale data defines the locale id for French as
+"fr". You can use the second parameter to associate the imported French locale data with the custom
+locale id "fr-FR instead of "fr".
+
The files in `@angular/common/locales` contain most of the locale data that you
need, but some advanced formatting options might only be available in the extra dataset that you can
import from `@angular/common/locales/extra`. An error message informs you when this is the case.
@@ -118,7 +142,6 @@ in the target language.
You need to build and deploy a separate version of the app for each supported language.
{@a i18n-attribute}
-
### Mark text with the i18n attribute
The Angular `i18n` attribute marks translatable content. Place it on every element tag whose fixed
@@ -144,7 +167,6 @@ To mark the greeting for translation, add the `i18n` attribute to the `
` tag
{@a help-translator}
-
### Help the translator with a description and meaning
To translate a text message accurately, the translator may need additional information or context.
@@ -175,7 +197,6 @@ text messages with different descriptions (not different meanings), then they ar
{@a custom-id}
-
### Set a custom id for persistence and maintenance
The angular i18n extractor tool generates a file with a translation unit entry for each `i18n`
@@ -250,7 +271,6 @@ the same text, `Bonjour`:
{@a no-element}
-
### Translate text without creating an element
If there is a section of text that you would like to translate, you can wrap it in a `` tag.
@@ -262,7 +282,6 @@ The `` is transformed into an html comment:
{@a translate-attributes}
-
## Add i18n translation attributes
You also can translate attributes.
@@ -286,7 +305,6 @@ You also can assign a meaning, description, and id with the `i18n-x="|<
syntax.
{@a plural-ICU}
-
## Translate singular and plural
Different languages have different pluralization rules.
@@ -342,7 +360,6 @@ for two, three, or any other number if the pluralization rules were different. F
{@a select-ICU}
-
## Select among alternative text messages
If your template needs to display different text messages depending on the value of a variable, you
@@ -360,7 +377,6 @@ The message maps those values to the appropriate translations:
{@a nesting-ICUS}
-
## Nesting plural and select ICU expressions
You can also nest different ICU expressions together, as shown in this example:
@@ -369,7 +385,6 @@ You can also nest different ICU expressions together, as shown in this example:
{@a ng-xi18n}
-
## Create a translation source file with _ng xi18n_
Use the `ng xi18n` command provided by the CLI to extract the text messages marked with `i18n` into
@@ -394,7 +409,6 @@ package, or you can manually use the CLI Webpack plugin `ExtractI18nPlugin` from
{@a other-formats}
-
### Other translation formats
Angular i18n tooling supports three translation formats:
@@ -422,7 +436,6 @@ The sample in this guide uses the default XLIFF 1.2 format.
{@a ng-xi18n-options}
-
### Other options
You can specify the output path used by the CLI to extract your translation source file with
@@ -456,7 +469,6 @@ file. This information is not used by Angular, but external translation tools ma
{@a translate}
-
## Translate text messages
The `ng xi18n` command generates a translation source file named `messages.xlf` in the project `src`
@@ -466,7 +478,6 @@ The next step is to translate this source file into the specific language
translation files. The example in this guide creates a French translation file.
{@a localization-folder}
-
### Create a localization folder
Most apps are translated into more than one other language. For this reason, it is standard practice
@@ -500,7 +511,6 @@ For this example:
If you were translating to other languages, you would repeat these steps for each target language.
{@a translate-text-nodes}
-
### Translate text nodes
In a large translation project, you would send the `messages.fr.xlf` file to a French translator who
@@ -544,7 +554,6 @@ This sample file is easy to translate without a special editor or knowledge of F
{@a translate-plural-select}
-
## Translate plural and select expressions
_Plural_ and _select_ ICU expressions are extracted separately, so they require special attention
@@ -555,7 +564,6 @@ elsewhere in the source template. In this example, you know the translation unit
must be just below the translation unit for the logo.
{@a translate-plural}
-
### Translate _plural_
To translate a `plural`, translate its ICU format match values:
@@ -567,7 +575,6 @@ You can add or remove plural cases, with each language having its own cardinalit
[CLDR plural rules](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html).)
{@a translate-select}
-
### Translate _select_
Below is the content of our example `select` ICU expression in the component template:
@@ -598,7 +605,6 @@ Here they are together, after translation:
{@a translate-nested}
-
### Translate a nested expression
A nested expression is similar to the previous examples. As in the previous example, there are
@@ -621,7 +627,6 @@ The entire template translation is complete. The next section describes how to l
into the app.
{@a app-pre-translation}
-
### The app and its translation file
The sample app and its translation file are now as follows:
@@ -640,7 +645,6 @@ The sample app and its translation file are now as follows:
{@a merge}
-
## Merge the completed translation file into the app
To merge the translated text into component templates, compile the app with the completed
@@ -656,12 +660,11 @@ format that Angular understands, such as `.xtb`.
How you provide this information depends upon whether you compile with
the JIT compiler or the AOT compiler.
- * With [AOT](guide/i18n#aot), you pass the information as a CLI parameter.
- * With [JIT](guide/i18n#jit), you provide the information at bootstrap time.
+ * With [AOT](guide/i18n#merge-aot), you pass the information as a CLI parameter.
+ * With [JIT](guide/i18n#merge-jit), you provide the information at bootstrap time.
-{@a aot}
-
+{@a merge-aot}
### Merge with the AOT compiler
The AOT (_Ahead-of-Time_) compiler is part of a build process that produces a small, fast,
@@ -685,8 +688,7 @@ guide:
ng serve --aot --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr
-{@a jit}
-
+{@a merge-jit}
### Merge with the JIT compiler
The JIT compiler compiles the app in the browser as the app loads.
@@ -713,3 +715,29 @@ Then provide the `LOCALE_ID` in the main module:
+
+
+{@a missing-translation}
+### Report missing translations
+By default, when a translation is missing, the build succeeds but generates a warning such as
+`Missing translation for message "foo"`. You can configure the level of warning that is generated by
+the Angular compiler:
+
+* Error: throw an error. If you are using AOT compilation, the build will fail. If you are using JIT
+compilation, the app will fail to load.
+* Warning (default): show a 'Missing translation' warning in the console or shell.
+* Ignore: do nothing.
+
+If you use the AOT compiler, specify the warning level by using the CLI parameter
+`--missingTranslation`. The example below shows how to set the warning level to error:
+
+
+ ng serve --aot --missingTranslation=error
+
+
+If you use the JIT compiler, specify the warning level in the compiler config at bootstrap by adding
+the 'MissingTranslationStrategy' property. The example below shows how to set the warning level to
+error:
+
+
+
diff --git a/packages/core/src/i18n/tokens.ts b/packages/core/src/i18n/tokens.ts
index da156b7fef..7bbec4939d 100644
--- a/packages/core/src/i18n/tokens.ts
+++ b/packages/core/src/i18n/tokens.ts
@@ -9,21 +9,95 @@
import {InjectionToken} from '../di/injection_token';
/**
+ * Provide this token to set the locale of your application.
+ * It is used for i18n extraction, by i18n pipes (DatePipe, I18nPluralPipe, CurrencyPipe,
+ * DecimalPipe and PercentPipe) and by ICU expressions.
+ *
+ * See the {@linkDocs guide/i18n#setting-up-locale i18n guide} for more information.
+ *
+ * ### Example
+ *
+ * ```typescript
+ * import { LOCALE_ID } from '@angular/core';
+ * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+ * import { AppModule } from './app/app.module';
+ *
+ * platformBrowserDynamic().bootstrapModule(AppModule, {
+ * providers: [{provide: LOCALE_ID, useValue: 'en-US' }]
+ * });
+ * ```
+ *
* @experimental i18n support is experimental.
*/
export const LOCALE_ID = new InjectionToken('LocaleId');
/**
+ * Use this token at bootstrap to provide the content of your translation file (`xtb`,
+ * `xlf` or `xlf2`) when you want to translate your application in another language.
+ *
+ * See the {@linkDocs guide/i18n#merge i18n guide} for more information.
+ *
+ * ### Example
+ *
+ * ```typescript
+ * import { TRANSLATIONS } from '@angular/core';
+ * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+ * import { AppModule } from './app/app.module';
+ *
+ * // content of your translation file
+ * const translations = '....';
+ *
+ * platformBrowserDynamic().bootstrapModule(AppModule, {
+ * providers: [{provide: TRANSLATIONS, useValue: translations }]
+ * });
+ * ```
+ *
* @experimental i18n support is experimental.
*/
export const TRANSLATIONS = new InjectionToken('Translations');
/**
+ * Provide this token at bootstrap to set the format of your {@link TRANSLATIONS}: `xtb`,
+ * `xlf` or `xlf2`.
+ *
+ * See the {@linkDocs guide/i18n#merge i18n guide} for more information.
+ *
+ * ### Example
+ *
+ * ```typescript
+ * import { TRANSLATIONS_FORMAT } from '@angular/core';
+ * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+ * import { AppModule } from './app/app.module';
+ *
+ * platformBrowserDynamic().bootstrapModule(AppModule, {
+ * providers: [{provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }]
+ * });
+ * ```
+ *
* @experimental i18n support is experimental.
*/
export const TRANSLATIONS_FORMAT = new InjectionToken('TranslationsFormat');
/**
+ * Use this enum at bootstrap as an option of `bootstrapModule` to define the strategy
+ * that the compiler should use in case of missing translations:
+ * - Error: throw if you have missing translations.
+ * - Warning (default): show a warning in the console and/or shell.
+ * - Ignore: do nothing.
+ *
+ * See the {@linkDocs guide/i18n#missing-translation i18n guide} for more information.
+ *
+ * ### Example
+ * ```typescript
+ * import { MissingTranslationStrategy } from '@angular/core';
+ * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+ * import { AppModule } from './app/app.module';
+ *
+ * platformBrowserDynamic().bootstrapModule(AppModule, {
+ * missingTranslation: MissingTranslationStrategy.Error
+ * });
+ * ```
+ *
* @experimental i18n support is experimental.
*/
export enum MissingTranslationStrategy {