5 lines
79 KiB
JSON
5 lines
79 KiB
JSON
{
|
|
"id": "guide/i18n",
|
|
"title": "Localizing your app",
|
|
"contents": "\n\n\n<div class=\"github-links\">\n <a href=\"https://github.com/angular/angular/edit/master/aio/content/guide/i18n.md?message=docs%3A%20describe%20your%20change...\" aria-label=\"Suggest Edits\" title=\"Suggest Edits\"><i class=\"material-icons\" aria-hidden=\"true\" role=\"img\">mode_edit</i></a>\n</div>\n\n\n<div class=\"content\">\n <h1 id=\"localizing-your-app\">Localizing your app<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#localizing-your-app\"><i class=\"material-icons\">link</i></a></h1>\n\n<a id=\"angular-i18n\"></a>\n<p><em>Internationalization</em> (i18n) is the process of designing and preparing your app to be usable in different locales around the world.\n<em>Localization</em> is the process of building versions of your app for different locales, including extracting text for translation into different languages, and formatting data for particular locales.</p>\n<p>A <em>locale</em> identifies a region (such as a country) in which people speak a particular language or language variant. The locale determines the formatting and parsing of dates, times, numbers, and currencies as well as measurement units and the translated names for time zones, languages, and countries.</p>\n<div class=\"alert is-helpful\">\n<p>Create an adaptable user interface for all of your target locales that takes into consideration the differences in spacing for different languages. For details, see <a href=\"https://marketfinder.thinkwithgoogle.com/intl/en_us/guide/how-to-approach-i18n/#overview\" title=\"How to approach internationalization\">How to approach internationalization</a>.</p>\n</div>\n<p>Use Angular to internationalize your app:</p>\n<ul>\n<li>Use built-in pipes to display dates, numbers, percentages, and currencies in a local format.</li>\n<li>Mark text in component templates for translation.</li>\n<li>Mark plural forms of expressions for translation.</li>\n<li>Mark alternate text for translation.</li>\n</ul>\n<p>After preparing your app for an international audience, use the <a href=\"cli\">Angular CLI</a> to localize your app by performing the following tasks:</p>\n<ul>\n<li>Use the CLI to extract marked text to a <em>source language</em> file.</li>\n<li>Make a copy of this file for each language, and send these <em>translation files</em> to a translator or service.</li>\n<li>Use the CLI to merge the finished translation files when building your app for one or more locales.</li>\n</ul>\n<div class=\"alert is-helpful\">\n<p> To explore the sample app with French translations used in this guide, see the <live-example></live-example>.</p>\n</div>\n<h2 id=\"prerequisites\">Prerequisites<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#prerequisites\"><i class=\"material-icons\">link</i></a></h2>\n<p>To prepare your app for translations, you should have a basic understanding of the following:</p>\n<ul>\n<li><a href=\"guide/glossary#template\" title=\"Definition of a template\">Templates</a></li>\n<li><a href=\"guide/glossary#component\" title=\"Definition of a component\">Components</a></li>\n<li><a href=\"guide/glossary#command-line-interface-cli\" title=\"Definition of CLI\">Angular CLI</a> command-line tool for managing the Angular development cycle</li>\n<li><a href=\"https://www.w3.org/XML/\" title=\"W3C: Extensible Markup Language (XML)\">Extensible Markup Language (XML)</a> used for translation files</li>\n</ul>\n<h2 id=\"steps-to-localize-your-app\">Steps to localize your app<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#steps-to-localize-your-app\"><i class=\"material-icons\">link</i></a></h2>\n<p>To localize your app, follow these general steps:</p>\n<ol>\n<li><a href=\"guide/i18n#setting-up-cli\">Add the localize package</a>.</li>\n<li><a href=\"guide/i18n#setting-up-locale\">Refer to locales by ID</a>.</li>\n<li><a href=\"guide/i18n#i18n-pipes\">Format data based on locale</a>.</li>\n<li><a href=\"guide/i18n#Template-translations\">Prepare templates for translations</a>.</li>\n<li><a href=\"guide/i18n#ng-xi18n\">Work with translation files</a>.</li>\n<li><a href=\"guide/i18n#merge\">Merge translations into the app</a>.</li>\n<li><a href=\"guide/i18n#deploy-locales\">Deploy multiple locales</a>.</li>\n</ol>\n<p>While following these steps, you can <a href=\"guide/i18n#app-pre-translation\">explore the translated example app</a>.</p>\n<p>The following are optional practices that may be required in special cases:</p>\n<ul>\n<li><a href=\"guide/i18n#set-source-manually\">Set the source locale manually</a> if you need to set the <a href=\"api/core/LOCALE_ID\" title=\"API reference for LOCALE_ID\">LOCALE_ID</a> token.</li>\n<li><a href=\"guide/i18n#import-locale\">Import global variants of the locale data</a> for extra locale data.</li>\n<li><a href=\"guide/i18n#custom-id\">Manage marked text with custom IDs</a> if you require more control over matching translations.</li>\n</ul>\n<a id=\"setting-up-cli\"></a>\n<a id=\"add-localize\"></a>\n<h2 id=\"add-the-localize-package\">Add the localize package<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#add-the-localize-package\"><i class=\"material-icons\">link</i></a></h2>\n<p>To take advantage of Angular's localization features, use the Angular CLI to add the <code>@angular/localize</code> package to your project:</p>\n<code-example language=\"sh\" class=\"code-shell\">\n ng add @angular/localize\n</code-example>\n<p>This command updates your project's <code>package.json</code> and <code>polyfills.ts</code> files to import the <code>@angular/localize</code> package.</p>\n<div class=\"alert is-helpful\">\n<p>For more information about <code>package.json</code> and polyfill packages, see <a href=\"guide/npm-packages\">Workspace npm dependencies</a>.</p>\n</div>\n<p>If <code>@angular/localize</code> is not installed, the Angular CLI may generate an error when you try to build a localized version of your app.</p>\n<a id=\"setting-up-locale\"></a>\n<a id=\"setting-up-the-locale-of-your-app\"></a>\n<h2 id=\"refer-to-locales-by-id\">Refer to locales by ID<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#refer-to-locales-by-id\"><i class=\"material-icons\">link</i></a></h2>\n<p>Refer to a locale using the Unicode <em>locale identifier</em> (ID), which specifies the language, country, and an optional code for further variants or subdivisions.</p>\n<div class=\"callout is-helpful\">\n<header>Unicode locale identifiers</header>\n<ul>\n<li>For a list of language codes, see <a href=\"https://www.loc.gov/standards/iso639-2/\" title=\"ISO 639-2 Registration Authority\">ISO 639-2</a>.</li>\n<li>IDs conform to the Unicode Common Locale Data Repository (CLDR).\nFor more information about Unicode locale identifiers, see the <a href=\"http://cldr.unicode.org/core-spec#Unicode_Language_and_Locale_Identifiers\" title=\"CLDR - Unicode Common Locale Data Repository\">CLDR core specification</a>.</li>\n<li>CLDR and Angular base their identifiers on <a href=\"https://tools.ietf.org/html/bcp47\" title=\"BCP47 Tags for Identifying Languages\">BCP47 tags</a>.</li>\n</ul>\n</div>\n<p>The ID consists of a language identifier, such as <code>en</code> for English or <code>fr</code> for French, followed by a dash (<code>-</code>) and a locale extension, such as <code>US</code> for the United States or <code>CA</code> for Canada.\nFor example, <code>en-US</code> refers to English in the United States, and <code>fr-CA</code> refers to French in Canada.\nAngular uses this ID to find the correct corresponding locale data.</p>\n<div class=\"alert is-helpful\">\n<p>Many countries, such as France and Canada, use the same language (French, identified as <code>fr</code>) but differ in grammar, punctuation, and formats for currency, decimal numbers, and dates.\nUse a more specific locale ID, such as French for Canada (<code>fr-CA</code>), when localizing your app.</p>\n</div>\n<p>Angular by default uses <code>en-US</code> (English in the United States) as your app's source locale.</p>\n<p>The <a href=\"https://github.com/angular/angular/tree/master/packages/common/locales\" title=\"Common locales in the Angular repository\">Angular repository</a> includes common locales.\nYou can change your app's source locale for the build by setting the source locale in the <code>sourceLocale</code> field of your app's <a href=\"guide/workspace-config\" title=\"Angular workspace configuration\">workspace configuration</a> file (<code>angular.json</code>).\nThe build process (described in <a href=\"guide/i18n#merge\">Merge translations into the app</a> in this guide) uses your app's <code>angular.json</code> file to automatically set the <a href=\"api/core/LOCALE_ID\" title=\"API reference for LOCALE_ID\"><code>LOCALE_ID</code></a> token and load the locale data.</p>\n<a id=\"i18n-pipes\"></a>\n<h2 id=\"format-data-based-on-locale\">Format data based on locale<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#format-data-based-on-locale\"><i class=\"material-icons\">link</i></a></h2>\n<p>Angular provides the following built-in data transformation <a href=\"guide/glossary#pipe\" title=\"Definition of a pipe\">pipes</a> that use the <a href=\"api/core/LOCALE_ID\" title=\"API reference for LOCALE_ID\"><code>LOCALE_ID</code></a> token to format data according to the locale's rules:</p>\n<ul>\n<li><a href=\"api/common/DatePipe\"><code>DatePipe</code></a>: Formats a date value.</li>\n<li><a href=\"api/common/CurrencyPipe\"><code>CurrencyPipe</code></a>: Transforms a number to a currency string.</li>\n<li><a href=\"/api/common/DecimalPipe\"><code>DecimalPipe</code></a>: Transforms a number into a decimal number string.</li>\n<li><a href=\"api/common/PercentPipe\"><code>PercentPipe</code></a>: Transforms a number to a percentage string.</li>\n</ul>\n<p>For example, <code>{{today | <a href=\"api/common/DatePipe\" class=\"code-anchor\">date</a>}}</code> uses <code><a href=\"api/common/DatePipe\" class=\"code-anchor\">DatePipe</a></code> to display the current date in the format for the locale in <code><a href=\"api/core/LOCALE_ID\" class=\"code-anchor\">LOCALE_ID</a></code>.</p>\n<p>To override the value of <code><a href=\"api/core/LOCALE_ID\" class=\"code-anchor\">LOCALE_ID</a></code>, add the <code>locale</code> parameter.\nFor example, to force the currency to use <code>en-US</code> no matter which language-locale you set for <code><a href=\"api/core/LOCALE_ID\" class=\"code-anchor\">LOCALE_ID</a></code>, use this form: <code>{{amount | <a href=\"api/common/CurrencyPipe\" class=\"code-anchor\">currency</a> : 'en-US'}}</code>.</p>\n<a id=\"Template-translations\"></a>\n<h2 id=\"prepare-templates-for-translations\">Prepare templates for translations<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#prepare-templates-for-translations\"><i class=\"material-icons\">link</i></a></h2>\n<p>To translate your app's templates, you need to prepare the text for a translator or translation service by marking text, attributes, and other elements with the Angular <code>i18n</code> attribute.\nFollow these general steps:</p>\n<ol>\n<li><a href=\"guide/i18n#i18n-attribute\">Mark text for translations</a>.</li>\n<li><a href=\"guide/i18n#help-translator\">Add helpful descriptions and meanings</a> to help the translator with additional information or context.</li>\n<li><a href=\"guide/i18n#no-element\">Translate text not for display</a>.</li>\n<li><a href=\"guide/i18n#translate-attributes\">Mark element attributes for translations</a>, such as an image's <code>title</code> attribute.</li>\n<li><a href=\"guide/i18n#plurals-alternates\">Mark plurals and alternates for translation</a> in order to comply with the pluralization rules and grammatical constructions of different languages.</li>\n</ol>\n<a id=\"i18n-attribute\"></a>\n<h3 id=\"mark-text-for-translations\">Mark text for translations<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#mark-text-for-translations\"><i class=\"material-icons\">link</i></a></h3>\n<p>Mark the static text messages in your component templates for translation using the <code>i18n</code> attribute.\nPlace it on every element tag with fixed text to be translated.</p>\n<p>For example, the following <code><h1></code> tag displays a simple English language greeting, \"Hello i18n!\"</p>\n<code-example path=\"i18n/doc-files/app.component.html\" region=\"greeting\" header=\"src/app/app.component.html\">\n<h1>Hello i18n!</h1>\n\n</code-example>\n<p>To mark the greeting for translation, add the <code>i18n</code> attribute to the <code><h1></code> tag.</p>\n<code-example path=\"i18n/doc-files/app.component.html\" region=\"i18n-attribute\" header=\"src/app/app.component.html\">\n<h1 i18n>Hello i18n!</h1>\n\n</code-example>\n<div class=\"alert is-helpful\">\n<p><code>i18n</code> is a custom attribute, recognized by Angular tools and compilers.\nAfter translation, the compiler removes it. It is not an Angular directive.</p>\n</div>\n<a id=\"help-translator\"></a>\n<h3 id=\"add-helpful-descriptions-and-meanings\">Add helpful descriptions and meanings<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#add-helpful-descriptions-and-meanings\"><i class=\"material-icons\">link</i></a></h3>\n<p>To translate a text message accurately, the translator may need additional information or context.\nAdd a <em>description</em> of the text message as the value of the <code>i18n</code> attribute, as shown in the following example:</p>\n<code-example path=\"i18n/doc-files/app.component.html\" region=\"i18n-attribute-desc\" header=\"src/app/app.component.html\">\n<h1 i18n=\"An introduction header for this sample\">Hello i18n!</h1>\n\n</code-example>\n<p>The translator may also need to know the meaning or intent of the text message within this particular app context, in order to translate it the same way as other text with the same meaning.\nStart the <code>i18n</code> attribute value with the <em>meaning</em> and\nseparate it from the <em>description</em> with the <code>|</code> character: <code><meaning>|<description></code>.</p>\n<p>For example, you can add the meaning that this <code><h1></code> tag is a site header that needs to be translated the same way not only when used as a header, but also when referred to from another section of text:</p>\n<code-example path=\"i18n/doc-files/app.component.html\" region=\"i18n-attribute-meaning\" header=\"src/app/app.component.html\">\n<h1 i18n=\"site header|An introduction header for this sample\">Hello i18n!</h1>\n\n</code-example>\n<p>As a result, any text marked with <code>site header</code> as the <em>meaning</em> is translated exactly the same way.</p>\n<a id=\"transaction-unit-ids\"></a>\n<div class=\"callout is-helpful\">\n<header>How meanings control text extraction and merging</header>\n<p>The Angular extraction tool (described in <a href=\"guide/i18n#ng-xi18n\">Work with translation files</a> in this guide) generates a translation unit entry for each <code>i18n</code>\nattribute in a template.\nIt assigns each translation unit a unique ID based on the <em>meaning</em> and <em>description</em>.</p>\n<p>The same text elements with different <em>meanings</em> are extracted with separate IDs.\nFor example, if the word \"right\" appears with the meaning <code>correct</code> (as in \"You are right\") in one place, and with the meaning <code>direction</code> (as in \"Turn right\") in another place, the word is translated differently and merged back into the app as different translation entries.</p>\n<p>If the same text elements have different <em>descriptions</em> but the same <em>meaning</em>, they are extracted only once, with only one ID. That one translation entry is merged back into the app wherever the same text elements appear.</p>\n</div>\n<a id=\"no-element\"></a>\n<h3 id=\"translate-text-not-for-display\">Translate text not for display<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#translate-text-not-for-display\"><i class=\"material-icons\">link</i></a></h3>\n<p>While you can translate non-displayed text using a <code><span></code> tag, you are creating a new DOM element. To avoid doing so, wrap the text in an <code><ng-container></code> element, which is transformed into a non-displayed HTML comment as shown in this example:</p>\n<code-example path=\"i18n/src/app/app.component.html\" region=\"i18n-ng-container\">\n<ng-container i18n>I don't output any element</ng-container>\n\n</code-example>\n<a id=\"translate-attributes\"></a>\n<h3 id=\"mark-element-attributes-for-translations\">Mark element attributes for translations<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#mark-element-attributes-for-translations\"><i class=\"material-icons\">link</i></a></h3>\n<p>HTML attributes such as <code>title</code> include text that should be translated along with the rest of the displayed text in the template.\nThe following example shows an image with a <code>title</code> attribute:</p>\n<code-example path=\"i18n/doc-files/app.component.html\" region=\"i18n-title\" header=\"src/app/app.component.html\">\n<img [src]=\"logo\" title=\"Angular logo\">\n\n</code-example>\n<p>To mark an attribute for translation, add <code>i18n-</code><em>attribute</em> in which <em>attribute</em> is the attribute to translate.\nThe following example shows how to mark the\n<code>title</code> attribute on the <code>img</code> tag by adding <code>i18n-title</code>:</p>\n<code-example path=\"i18n/src/app/app.component.html\" region=\"i18n-title-translate\" header=\"src/app/app.component.html\">\n<img [src]=\"logo\" i18n-title title=\"Angular logo\" />\n\n</code-example>\n<p>You can use <code>i18n-</code><em>attribute</em> with any attribute of any element.\nYou also can assign a meaning, description, and custom ID with the <code>i18n-</code><em>attribute</em><code>=\"<meaning>|<description>@@<id>\"</code> syntax.</p>\n<a id=\"plurals-alternates\"></a>\n<h3 id=\"mark-plurals-and-alternates-for-translation\">Mark plurals and alternates for translation<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#mark-plurals-and-alternates-for-translation\"><i class=\"material-icons\">link</i></a></h3>\n<p>Different languages have different pluralization rules and grammatical constructions that can make translation difficult.\nTo simplify translation, use International Components for Unicode (ICU) clauses with regular expressions, such as <code>plural</code> to mark the uses of plural numbers, and <code>select</code> to mark alternate text choices.</p>\n<div class=\"alert is-helpful\">\n<p>The ICU clauses adhere to the <a href=\"http://userguide.icu-project.org/formatparse/messages\" title=\"ICU Message Format\">ICU Message Format</a> specified in the <a href=\"http://cldr.unicode.org/index/cldr-spec/plural-rules\" title=\"Pluralization Rules\">CLDR pluralization rules</a>.</p>\n</div>\n<a id=\"plural-ICU\"></a>\n<h4 id=\"mark-plurals\">Mark plurals<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#mark-plurals\"><i class=\"material-icons\">link</i></a></h4>\n<p>Use the <code>plural</code> clause to mark expressions that may not be meaningful if translated word-for-word.</p>\n<p>For example, if you want to display \"updated x minutes ago\" in English, you may want to display \"just now\", \"one minute ago\", or \"<em>x</em> minutes ago\" (with <em>x</em> as the actual number).\nOther languages might express this cardinality differently.\nThe following example shows how to use a <code>plural</code> clause to express these three options:</p>\n<code-example path=\"i18n/src/app/app.component.html\" region=\"i18n-plural\" header=\"src/app/app.component.html\">\n<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>\n\n</code-example>\n<p>In the above example:</p>\n<ul>\n<li>\n<p>The first parameter, <code>minutes</code>, is bound to the component property (<code>minutes</code>), which determines the number of minutes.</p>\n</li>\n<li>\n<p>The second parameter identifies this as a <code>plural</code> translation type.</p>\n</li>\n<li>\n<p>The third parameter defines a pattern of pluralization categories and their matching values:</p>\n<ul>\n<li>For zero minutes, use <code>=0 {just now}</code>.</li>\n<li>For one minute, use <code>=1 {one minute}</code>.</li>\n<li>For any unmatched cardinality, use <code>other {{{minutes}} minutes ago}</code>.\nYou can use HTML markup and <a href=\"guide/glossary#interpolation\" title=\"Definition of interpolation\">interpolations</a> such as <code>{{{minutes}}</code> with the <code>plural</code> clause in expressions.</li>\n<li>After the pluralization category, put the default text (English) within braces (<code>{}</code>).</li>\n</ul>\n</li>\n</ul>\n<p>Pluralization categories include (depending on the language):</p>\n<ul>\n<li><code>=0</code> (or any other number)</li>\n<li><code>zero</code></li>\n<li><code>one</code></li>\n<li><code>two</code></li>\n<li><code>few</code></li>\n<li><code>many</code></li>\n<li><code>other</code></li>\n</ul>\n<div class=\"callout is-important\">\n<header>Locales may not support some pluralization categories</header>\n<p>Many locales don't support some of the pluralization categories.\nFor example, the default locale (<code>en-US</code>) and other locales (such as <code>es</code>) have very simple <code>plural()</code> functions that don't support the <code>few</code> category.\nThe following shows the <a href=\"https://github.com/angular/angular/blob/ecffc3557fe1bff9718c01277498e877ca44588d/packages/core/src/i18n/locale_en.ts#L15-L18\">en-US</a> <code>plural()</code> function:</p>\n<code-example>\nfunction plural(n: number): number {\n let i = Math.floor(Math.abs(n)), v = n.toString().replace(/^[^.]*\\.?/, '').length;\n if (i === 1 && v === 0) return 1;\n return 5;\n}\n</code-example>\n<p>The function will only ever return 1 (<code>one</code>) or 5 (<code>other</code>).\nThe <code>few</code> category will never match.\nIf none of the pluralization categories match, Angular will try to match <code>other</code>.\nUse <code>other</code> as the standard fallback for a missing category.</p>\n<p>For more information about pluralization categories, see <a href=\"http://cldr.unicode.org/index/cldr-spec/plural-rules#TOC-Choosing-Plural-Category-Names\">Choosing plural category names</a> in the CLDR - Unicode Common Locale Data Repository.</p>\n</div>\n<a id=\"select-ICU\"></a>\n<a id=\"nesting-ICUS\"></a>\n<h3 id=\"mark-alternates-and-nested-expressions\">Mark alternates and nested expressions<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#mark-alternates-and-nested-expressions\"><i class=\"material-icons\">link</i></a></h3>\n<p>If you need to display alternate text depending on the value of a variable, you\nneed to translate all of the alternates.</p>\n<p>The <code>select</code> clause, similar to the <code>plural</code> clause, marks choices for alternate text based on your defined string values.\nFor example, the following clause in the component template binds to the component's <code>gender</code> property, which outputs one of the following string values: \"male\", \"female\" or \"other\".\nThe clause maps those values to the appropriate translations:</p>\n<code-example path=\"i18n/src/app/app.component.html\" region=\"i18n-select\" header=\"src/app/app.component.html\">\n<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>\n\n</code-example>\n<p>You can also nest different clauses together, such as the <code>plural</code> and <code>select</code> clauses in the following example:</p>\n<code-example path=\"i18n/src/app/app.component.html\" region=\"i18n-nested\" header=\"src/app/app.component.html\">\n<span i18n>Updated: {minutes, plural,\n =0 {just now}\n =1 {one minute ago}\n other {{{minutes}} minutes ago by {gender, select, male {male} female {female} other {other}}}}\n</span>\n\n</code-example>\n<a id=\"ng-xi18n\"></a>\n<a id=\"ng-xi18n-options\"></a>\n<a id=\"translate\"></a>\n<h2 id=\"work-with-translation-files\">Work with translation files<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#work-with-translation-files\"><i class=\"material-icons\">link</i></a></h2>\n<p>After preparing a template for translation, use the Angular CLI <code>extract-i18n</code> command to extract the marked text in the template into a <em>source language</em> file.\nThe marked text includes text marked with <code>i18n</code> and attributes marked with <code>i18n-</code><em>attribute</em> as described in the previous section.\nFollow these steps:</p>\n<ol>\n<li><a href=\"guide/i18n#create-source\">Extract the source language file</a>.\nYou can optionally change the location, format, and name.</li>\n<li><a href=\"guide/i18n#localization-folder\">Create a translation file for each language</a> by copying the source language file.</li>\n<li><a href=\"guide/i18n#translate-text-nodes\">Translate each translation file</a>.</li>\n<li><a href=\"guide/i18n#translate-plural-select\">Translate plurals and alternate expressions</a> separately.</li>\n</ol>\n<a id=\"create-source\"></a>\n<h3 id=\"extract-the-source-language-file\">Extract the source language file<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#extract-the-source-language-file\"><i class=\"material-icons\">link</i></a></h3>\n<p>To extract the source language file, open a terminal window, change to the root directory of your app project, and run the following CLI command:</p>\n<code-example language=\"sh\" class=\"code-shell\">\n ng extract-i18n\n</code-example>\n<p>The <code>extract-i18n</code> command creates a source language file named <code>messages.xlf</code> in your project's root directory using the <a href=\"https://en.wikipedia.org/wiki/XLIFF\" title=\"Wikipedia page about XLIFF\">XML Localization Interchange File Format (XLIFF, version 1.2)</a>.</p>\n<p>Use the following <code>extract-i18n</code> command options to change the source language file location, format, and file name:</p>\n<ul>\n<li><code>--output-path</code>: Change the location.</li>\n<li><code>--format</code>: Change the format.</li>\n<li><code>--outFile</code>: Change the file name.</li>\n</ul>\n<p>Note: The <code>--i18n-locale</code> option is deprecated.\nAngular 9 uses the source locale configured in your app's <a href=\"guide/workspace-config\" title=\"Angular workspace configuration\">workspace configuration</a> file (<code>angular.json</code>).</p>\n<h4 id=\"change-the-source-language-file-location\">Change the source language file location<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#change-the-source-language-file-location\"><i class=\"material-icons\">link</i></a></h4>\n<p>To create a file in the <code>src/locale</code> directory, specify the output path as an option, as shown in the following example:</p>\n<code-example language=\"sh\" class=\"code-shell\">\n ng extract-i18n --output-path src/locale\n</code-example>\n<a id=\"other-formats\"></a>\n<h4 id=\"change-the-source-language-file-format\">Change the source language file format<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#change-the-source-language-file-format\"><i class=\"material-icons\">link</i></a></h4>\n<p>The <code>extract-i18n</code> command can read and write files in three translation formats:</p>\n<ul>\n<li>XLIFF 1.2 (default)</li>\n<li>XLIFF 2</li>\n<li><a href=\"http://cldr.unicode.org/development/development-process/design-proposals/xmb\">XML Message Bundle (XMB)</a></li>\n</ul>\n<p>Specify the translation format explicitly with the <code>--format</code> command option, as shown in the following examples:</p>\n<code-example language=\"sh\" class=\"code-shell\">\nng extract-i18n --format=xlf\nng extract-i18n --format=xlf2\nng extract-i18n --format=xmb\n</code-example>\n<div class=\"alert is-helpful\">\n<p> XLIFF files use the extension <code>.xlf</code>.\nThe XMB format generates <code>.xmb</code> source language files but uses<code>.xtb</code> (XML Translation Bundle: XTB) translation files.</p>\n</div>\n<h4 id=\"change-the-source-language-file-name\">Change the source language file name<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#change-the-source-language-file-name\"><i class=\"material-icons\">link</i></a></h4>\n<p>To change the name of the source language file generated by the extraction tool, use\nthe <code>--outFile</code> command option:</p>\n<code-example language=\"sh\" class=\"code-shell\">\n ng extract-i18n --out-file source.xlf\n</code-example>\n<a id=\"localization-folder\"></a>\n<h3 id=\"create-a-translation-file-for-each-language\">Create a translation file for each language<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#create-a-translation-file-for-each-language\"><i class=\"material-icons\">link</i></a></h3>\n<p>The <code>ng extract-i18n</code> command (with no options) generates a source language file named <code>messages.xlf</code> in the project <code>src</code> folder.\nCreate <em>translation</em> files for each language by copying the source language file.\nTo avoid confusion with multiple translations, you should organize the language translation files by locale in a dedicated <code>locale</code> folder under <code>src/</code>.\nUse a filename extension that matches the associated locale, such as <code>messages.fr.xlf</code>.</p>\n<p>For example, to create a French translation file, follow these steps:</p>\n<ol>\n<li>Make a copy of the <code>messages.xlf</code> source language file.</li>\n<li>Put the copy in the <code>src/locale</code> folder.</li>\n<li>Rename the copy to <code>messages.fr.xlf</code> for the French language (<code>fr</code>) translation.\nSend this translation file to the translator.</li>\n</ol>\n<p>Repeat the above steps for each language you want to add to your app.</p>\n<a id=\"translate-text-nodes\"></a>\n<h3 id=\"translate-each-translation-file\">Translate each translation file<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#translate-each-translation-file\"><i class=\"material-icons\">link</i></a></h3>\n<p>Unless you are fluent in the language and have the time to edit translations, you would likely send each translation file to a translator, who would then use an XLIFF file editor to create and edit the translation.</p>\n<p>To demonstrate this process, see the <code>messages.fr.xlf</code> file in the <live-example></live-example>, which includes a French translation you can edit without a special XLIFF editor or knowledge of French.\nFollow these steps:</p>\n<ol>\n<li>Open <code>messages.fr.xlf</code> and find the first <code><trans-unit></code> element. This is a <em>translation unit</em>, also known as a <em>text node</em>, representing the translation of the <code><h1></code> greeting tag that was previously marked with the <code>i18n</code> attribute:</li>\n</ol>\n<blockquote>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translated-hello-before\" header=\"src/locale/messages.fr.xlf (<trans-unit>)\">\n<trans-unit id=\"introductionHeader\" datatype=\"html\">\n <source>Hello i18n!</source>\n <note priority=\"1\" from=\"description\">An introduction header for this sample</note>\n <note priority=\"1\" from=\"meaning\">User welcome</note>\n</trans-unit>\n\n</code-example>\n<p>The <code>id=\"introductionHeader\"\"</code> is a <a href=\"guide/i18n#custom-id\" title=\"Manage marked text with custom IDs\">custom ID</a>, but without the <code>@@</code> prefix required in the source HTML.</p>\n</blockquote>\n<ol start=\"2\">\n<li>Duplicate the <code><source>...</source></code> element in the text node, rename it <code>target</code>, and then replace its content with the French text:</li>\n</ol>\n<blockquote>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translated-hello\" header=\"src/locale/messages.fr.xlf (<trans-unit>, after translation)\">\n<trans-unit id=\"introductionHeader\" datatype=\"html\">\n <source>Hello i18n!</source>\n <target>Bonjour i18n !</target>\n <note priority=\"1\" from=\"description\">An introduction header for this sample</note>\n <note priority=\"1\" from=\"meaning\">User welcome</note>\n</trans-unit>\n\n</code-example>\n<p>In a more complex translation, the information and context in the <a href=\"guide/i18n#help-translator\" title=\"Add helpful descriptions and meanings\">description and meaning elements</a> described previously would help you choose the right words for translation.</p>\n</blockquote>\n<ol start=\"3\">\n<li>Translate the other text nodes the same way as shown in the following example:</li>\n</ol>\n<blockquote>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translated-other-nodes\" header=\"src/locale/messages.fr.xlf (<trans-unit>)\">\n<trans-unit id=\"ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3\" datatype=\"html\">\n <source>I don&apos;t output any element</source>\n <target>Je n'affiche aucun élément</target>\n</trans-unit>\n<trans-unit id=\"701174153757adf13e7c24a248c8a873ac9f5193\" datatype=\"html\">\n <source>Angular logo</source>\n <target>Logo d'Angular</target>\n</trans-unit>\n\n</code-example>\n</blockquote>\n<div class=\"alert is-important\">\n<p> Don't change the IDs for translation units.\nEach <code>id</code> is generated by Angular and depends on the content of the template text and its assigned meaning.\nIf you change either the text or the meaning, then the <code>id</code> changes.\nFor more about managing text updates and IDs, see the previous section on <a href=\"guide/i18n#custom-id\" title=\"Manage marked text with custom IDs\">custom IDs</a>.</p>\n</div>\n<a id=\"translate-plural-select\"></a>\n<h3 id=\"translate-plurals-and-alternate-expressions\">Translate plurals and alternate expressions<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#translate-plurals-and-alternate-expressions\"><i class=\"material-icons\">link</i></a></h3>\n<p>The <a href=\"guide/i18n#plurals-alternates\" title=\"Mark plurals and alternates for translation\"><code>plural</code> and <code>select</code> ICU expressions</a> are extracted as additional messages, so you must translate them separately.</p>\n<a id=\"translate-plural\"></a>\n<h4 id=\"translate-plurals\">Translate plurals<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#translate-plurals\"><i class=\"material-icons\">link</i></a></h4>\n<p>To translate a <code>plural</code>, translate its ICU format match values as shown in the following example:</p>\n<ul>\n<li><code>just now</code></li>\n<li><code>one minute ago</code></li>\n<li><code><x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes ago</code></li>\n</ul>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translated-plural\" header=\"src/locale/messages.fr.xlf (<trans-unit>)\">\n<trans-unit id=\"5a134dee893586d02bffc9611056b9cadf9abfad\" datatype=\"html\">\n <source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes ago} }</source>\n <target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes} }</target>\n</trans-unit>\n\n</code-example>\n<p>You can add or remove plural cases as needed for each language.</p>\n<div class=\"alert is-helpful\">\n<p>For language plural rules, see\n<a href=\"http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html\" title=\"CLDR Charts to view the Common Locale Data Repository data\">CLDR plural rules</a>.</p>\n</div>\n<a id=\"translate-select\"></a>\n<h4 id=\"translate-alternate-expressions\">Translate alternate expressions<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#translate-alternate-expressions\"><i class=\"material-icons\">link</i></a></h4>\n<p>Angular also extracts alternate <code>select</code> ICU expressions as separate translation units.\nThe following shows a <code>select</code> ICU expression in the component template:</p>\n<code-example path=\"i18n/src/app/app.component.html\" region=\"i18n-select\" header=\"src/app/app.component.html\">\n<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>\n\n</code-example>\n<p>In this example, Angular extracts the expression into two translation units. The first contains the text outside of the <code>select</code> clause, and uses a placeholder for <code>select</code> (<code><x id=\"ICU\"></code>):</p>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translate-select-1\" header=\"src/locale/messages.fr.xlf (<trans-unit>)\">\n<trans-unit id=\"f99f34ac9bd4606345071bd813858dec29f3b7d1\" datatype=\"html\">\n <source>The author is <x id=\"ICU\" equiv-text=\"{gender, select, male {...} female {...} other {...}}\"/></source>\n <target>L'auteur est <x id=\"ICU\" equiv-text=\"{gender, select, male {...} female {...} other {...}}\"/></target>\n</trans-unit>\n\n</code-example>\n<div class=\"alert is-important\">\n<p>When translating the text, you can move the placeholder if necessary, but don't remove it.\nIf you remove the placeholder, the ICU expression will not appear in your translated app.</p>\n</div>\n<p>The second translation unit contains the <code>select</code> clause:</p>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translate-select-2\" header=\"src/locale/messages.fr.xlf (<trans-unit>)\">\n<trans-unit id=\"eff74b75ab7364b6fa888f1cbfae901aaaf02295\" datatype=\"html\">\n <source>{VAR_SELECT, select, male {male} female {female} other {other} }</source>\n <target>{VAR_SELECT, select, male {un homme} female {une femme} other {autre} }</target>\n</trans-unit>\n\n</code-example>\n<p>The following example shows both translation units after translating:</p>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translated-select\" header=\"src/locale/messages.fr.xlf (<trans-unit>)\">\n<trans-unit id=\"f99f34ac9bd4606345071bd813858dec29f3b7d1\" datatype=\"html\">\n <source>The author is <x id=\"ICU\" equiv-text=\"{gender, select, male {...} female {...} other {...}}\"/></source>\n <target>L'auteur est <x id=\"ICU\" equiv-text=\"{gender, select, male {...} female {...} other {...}}\"/></target>\n</trans-unit>\n<trans-unit id=\"eff74b75ab7364b6fa888f1cbfae901aaaf02295\" datatype=\"html\">\n <source>{VAR_SELECT, select, male {male} female {female} other {other} }</source>\n <target>{VAR_SELECT, select, male {un homme} female {une femme} other {autre} }</target>\n</trans-unit>\n\n</code-example>\n<a id=\"translate-nested\"></a>\n<h4 id=\"translate-nested-expressions\">Translate nested expressions<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#translate-nested-expressions\"><i class=\"material-icons\">link</i></a></h4>\n<p>Angular treats a nested expression in the same manner as an alternate expression, extracting it into two translation units. The first contains the text outside of the nested expression:</p>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translate-nested-1\" header=\"src/locale/messages.fr.xlf (<trans-unit>)\">\n<trans-unit id=\"972cb0cf3e442f7b1c00d7dab168ac08d6bdf20c\" datatype=\"html\">\n <source>Updated: <x id=\"ICU\" equiv-text=\"{minutes, plural, =0 {...} =1 {...} other {...}}\"/></source>\n <target>Mis à jour: <x id=\"ICU\" equiv-text=\"{minutes, plural, =0 {...} =1 {...} other {...}}\"/></target>\n</trans-unit>\n\n</code-example>\n<p>The second translation unit contains the complete nested expression:</p>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translate-nested-2\" header=\"src/locale/messages.fr.xlf (<trans-unit>)\">\n<trans-unit id=\"7151c2e67748b726f0864fc443861d45df21d706\" datatype=\"html\">\n <source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes ago by {VAR_SELECT, select, male {male} female {female} other {other} }} }</source>\n <target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes par {VAR_SELECT, select, male {un homme} female {une femme} other {autre} }} }</target>\n</trans-unit>\n\n</code-example>\n<p>The following example shows both translation units after translating:</p>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" region=\"translate-nested\" header=\"src/locale/messages.fr.xlf (<trans-unit>)\">\n<trans-unit id=\"972cb0cf3e442f7b1c00d7dab168ac08d6bdf20c\" datatype=\"html\">\n <source>Updated: <x id=\"ICU\" equiv-text=\"{minutes, plural, =0 {...} =1 {...} other {...}}\"/></source>\n <target>Mis à jour: <x id=\"ICU\" equiv-text=\"{minutes, plural, =0 {...} =1 {...} other {...}}\"/></target>\n</trans-unit>\n<trans-unit id=\"7151c2e67748b726f0864fc443861d45df21d706\" datatype=\"html\">\n <source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes ago by {VAR_SELECT, select, male {male} female {female} other {other} }} }</source>\n <target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes par {VAR_SELECT, select, male {un homme} female {une femme} other {autre} }} }</target>\n</trans-unit>\n\n</code-example>\n<a id=\"merge\"></a>\n<a id=\"merge-aot\"></a>\n<h2 id=\"merge-translations-into-the-app\">Merge translations into the app<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#merge-translations-into-the-app\"><i class=\"material-icons\">link</i></a></h2>\n<p>To merge the completed translations into the app, use the <a href=\"guide/glossary#command-line-interface-cli\" title=\"Definition of CLI\">Angular CLI</a> to build a copy of the app's distributable files for each locale.\nThe build process replaces the original text with translated text, and sets the <code><a href=\"api/core/LOCALE_ID\" class=\"code-anchor\">LOCALE_ID</a></code> token for each distributable copy of the app.\nIt also loads and registers the locale data.</p>\n<p>After merging, you can serve each distributable copy of the app using server-side language detection or different subdirectories, as described in the next section about <a href=\"guide/i18n#deploy-locales\">deploying multiple locales</a>.</p>\n<p>The build process uses <a href=\"guide/glossary#ahead-of-time-aot-compilation\">ahead-of-time (AOT) compilation</a> to produce a small, fast,\nready-to-run app. With Ivy in Angular version 9, AOT is used by default for both\ndevelopment and production builds, and AOT is required to localize component templates.</p>\n<div class=\"alert is-helpful\">\n<p>For a detailed explanation the build process, see <a href=\"guide/build\" title=\"Building and serving Angular apps\">Building and serving Angular apps</a>.\nThis build process works for translation files in the <code>.xlf</code> format or in another format that Angular understands, such as <code>.xtb</code>.</p>\n</div>\n<div class=\"alert is-important\">\n<p>Ivy does not support merging i18n translations when using JIT mode.\nIf you <a href=\"guide/ivy#opting-out-of-ivy-in-version-9\">disable Ivy</a> and are using JIT mode, see <a href=\"https://v8.angular.io/guide/i18n#merge-with-the-jit-compiler\" title=\"Merge with the JIT compiler\">merging with the JIT compiler</a>.</p>\n</div>\n<p>To build a separate distributable copy of the app for each locale, <a href=\"guide/i18n#localize-config\">define the locales in the build configuration</a> in your project's workspace configuration file <a href=\"guide/workspace-config\" title=\"Angular workspace configuration\"><code>angular.json</code></a>.\nThis method shortens the build process by removing the requirement to perform a full app build for each locale.</p>\n<p>You can then <a href=\"guide/i18n#localize-generate\">generate app versions for each locale</a> using the <code>\"localize\"</code> option in <code>angular.json</code>. You can also <a href=\"guide/i18n#localize-build-command\">build from the command line</a> using the Angular CLI <a href=\"/cli/build\" title=\"CLI reference for ng build\"><code>build</code></a> command with the <code>--localize</code> option.</p>\n<div class=\"alert is-helpful\">\n<p>You can optionally <a href=\"guide/i18n#localize-build-one-locale\">apply specific build options for just one locale</a> for a custom locale configuration.</p>\n</div>\n<a id=\"localize-config\"></a>\n<h3 id=\"define-locales-in-the-build-configuration\">Define locales in the build configuration<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#define-locales-in-the-build-configuration\"><i class=\"material-icons\">link</i></a></h3>\n<p>Use the <code>i18n</code> project option in your app's build configuration file (<a href=\"guide/workspace-config\" title=\"Angular workspace configuration\"><code>angular.json</code></a>) to define locales for a project.\nThe following sub-options identify the source language and tell the compiler where to find supported translations for the project:</p>\n<ul>\n<li><code>sourceLocale</code>: The locale you use within the app source code (<code>en-US</code> by default)</li>\n<li><code>locales</code>: A map of locale identifiers to translation files</li>\n</ul>\n<p>For example, the following excerpt of an <code>angular.json</code> file sets the source locale to <code>en-US</code> and provides the path to the <code>fr</code> (French) locale translation file:</p>\n<code-example language=\"json\" header=\"angular.json\">\n...\n\"projects\": {\n \"angular.io-example\": {\n ...\n \"i18n\": {\n \"sourceLocale\": \"en-US\",\n \"locales\": {\n \"fr\": \"src/locale/messages.fr.xlf\"\n }\n },\n \"architect\": {\n ...\n }\n}\n</code-example>\n<a id=\"localize-generate\"></a>\n<h3 id=\"generate-app-versions-for-each-locale\">Generate app versions for each locale<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#generate-app-versions-for-each-locale\"><i class=\"material-icons\">link</i></a></h3>\n<p>To use your locale definition in the build configuration, use the <code>\"localize\"</code> option in <code>angular.json</code> to tell the CLI which locales to generate for the build configuration:</p>\n<ul>\n<li>Set <code>\"localize\"</code> to <code>true</code> for <em>all</em> the locales previously defined in the build configuration.</li>\n<li>Set <code>\"localize\"</code> to an array of a subset of the previously-defined locale identifiers to build only those locale versions.</li>\n<li>Set <code>\"localize\"</code> to <code>false</code> to disable localization and not generate any locale-specific versions.</li>\n</ul>\n<div class=\"alert is-helpful\">\n<p>Note: <a href=\"guide/glossary#ahead-of-time-aot-compilation\">Ahead-of-time (AOT) compilation</a> is required to localize component templates.\nIf you changed this setting, set <code>\"aot\"</code> to <code>true</code> in order to use AOT.</p>\n</div>\n<p>The following example shows the <code>\"localize\"</code> option set to <code>true</code> in <code>angular.json</code> so that all locales defined in the build configuration are built:</p>\n<code-example language=\"json\" header=\"angular.json\">\n\"build\": {\n \"builder\": \"@angular-devkit/build-angular:browser\",\n \"options\": {\n \"localize\": true,\n \"aot\": true,\n ...\n</code-example>\n<div class=\"alert is-helpful\">\n<p>Due to the deployment complexities of i18n and the need to minimize rebuild time, the development server only supports localizing a single locale at a time.\nSetting the <code>\"localize\"</code> option to <code>true</code> will cause an error when using <code>ng serve</code> if more than one locale is defined.\nSetting the option to a specific locale, such as <code>\"localize\": [\"fr\"]</code>, can work if you want to develop against a specific locale (such as <code>fr</code>).</p>\n</div>\n<p>The CLI loads and registers the locale data, places each generated version in a locale-specific directory to keep it separate from other locale versions, and puts the directories within the configured <code>outputPath</code> for the project.\nFor each application variant the <code>lang</code> attribute of the <code>html</code> element is set to the locale.\nThe CLI also adjusts the HTML base HREF for each version of the app by adding the locale to the configured <code>baseHref</code>.</p>\n<p>You can set the <code>\"localize\"</code> property as a shared configuration that all the configurations effectively inherit (or can override).</p>\n<a id=\"localize-build-command\"></a>\n<h3 id=\"build-from-the-command-line\">Build from the command line<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#build-from-the-command-line\"><i class=\"material-icons\">link</i></a></h3>\n<p>You can also use the <code>--localize</code> option with the <a href=\"/cli/build\" title=\"CLI reference for ng build\"><code>ng build</code></a> command and your existing <code>production</code> configuration.\nThe CLI builds all locales defined in the build configuration, which is similar to setting the <code>\"localize\"</code> option to <code>true</code> as described in the previous section.</p>\n<code-example language=\"sh\" class=\"code-shell\">\n ng build --localize\n</code-example>\n<a id=\"localize-build-one-locale\"></a>\n<h3 id=\"apply-specific-build-options-for-just-one-locale\">Apply specific build options for just one locale<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#apply-specific-build-options-for-just-one-locale\"><i class=\"material-icons\">link</i></a></h3>\n<p>To apply specific build options to only one locale, you can create a custom locale-specific configuration by specifying a single locale as shown in the following example:</p>\n<code-example language=\"json\" header=\"angular.json\">\n\"build\": {\n ...\n \"configurations\": {\n ...\n \"fr\": {\n \"localize\": [\"fr\"],\n \"main\": \"src/main.fr.ts\",\n ...\n }\n }\n},\n\"serve\": {\n ...\n \"configurations\": {\n ...\n \"fr\": {\n \"browserTarget\": \"*project-name*:build:fr\"\n }\n }\n}\n</code-example>\n<p>You can then pass this configuration to the <code>ng serve</code> or <code>ng build</code> commands.\nThe following shows how to serve the French language file created in the example for this guide:</p>\n<code-example language=\"sh\" class=\"code-shell\">\n ng serve --configuration=fr\n</code-example>\n<div class=\"alert is-important\">\n<p>You can use the CLI development server (<code>ng serve</code>), but only with a single locale.</p>\n</div>\n<p>For production builds, you can use configuration composition to execute both configurations:</p>\n<code-example language=\"sh\" class=\"code-shell\">\n ng build --configuration=production,fr\n</code-example>\n<code-example language=\"json\" header=\"angular.json\">\n...\n\"architect\": {\n \"build\": {\n \"builder\": \"@angular-devkit/build-angular:browser\",\n \"options\": { ... },\n \"configurations\": {\n \"fr\": {\n \"localize\": [\"fr\"],\n }\n }\n },\n ...\n \"serve\": {\n \"builder\": \"@angular-devkit/build-angular:dev-server\",\n \"options\": {\n \"browserTarget\": \"my-project:build\"\n },\n \"configurations\": {\n \"production\": {\n \"browserTarget\": \"my-project:build:production\"\n },\n \"fr\": {\n \"browserTarget\": \"my-project:build:fr\"\n }\n }\n }\n}\n</code-example>\n<a id=\"missing-translation\"></a>\n<h3 id=\"report-missing-translations\">Report missing translations<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#report-missing-translations\"><i class=\"material-icons\">link</i></a></h3>\n<p>When a translation is missing, the build succeeds but generates a warning such as\n<code>Missing translation for message \"foo\"</code>. You can configure the level of warning that is generated by the Angular compiler:</p>\n<ul>\n<li><code>error</code>: Throw an error. If you are using AOT compilation, the build will fail.\nIf you are using JIT compilation, the app will fail to load.</li>\n<li><code>warning</code> (default): Show a <code>Missing translation</code> warning in the console or shell.</li>\n<li><code>ignore</code>: Do nothing.</li>\n</ul>\n<p>Specify the warning level in the <code>options</code> section for the <code>build</code> target of your Angular CLI configuration file (<code>angular.json</code>). The following example shows how to set the warning level to <code>error</code>:</p>\n<code-example language=\"json\" header=\"angular.json\">\n\"options\": {\n ...\n \"i18nMissingTranslation\": \"error\"\n}\n</code-example>\n<a id=\"deploy-locales\"></a>\n<h2 id=\"deploy-multiple-locales\">Deploy multiple locales<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#deploy-multiple-locales\"><i class=\"material-icons\">link</i></a></h2>\n<p>If <code>myapp</code> is the directory containing your app's distributable files, you would typically make available different versions for different locales in locale directories such as <code>myapp/fr</code> for the French version and <code>myapp.com/es</code> for the Spanish version.</p>\n<p>The HTML <code>base</code> tag with the <code>href</code> attribute specifies the base URI, or URL, for relative links. If you set the <code>\"localize\"</code> option in <code>angular.json</code> to <code>true</code> or to an array of locale IDs, the CLI adjusts the base <code>href</code> for each version of the app by adding the locale to the configured <code>\"baseHref\"</code>. You can specify the <code>\"baseHref\"</code> for each locale in your workspace configuration file (<code>angular.json</code>), as shown in the following example, which sets <code>\"baseHref\"</code> to an empty string:</p>\n<code-example language=\"json\" header=\"angular.json\">\n...\n\"projects\": {\n \"angular.io-example\": {\n ...\n \"i18n\": {\n \"sourceLocale\": \"en-US\",\n \"locales\": {\n \"fr\": {\n \"translation\": \"src/locale/messages.fr.xlf\",\n \"baseHref\": \"\"\n }\n }\n },\n \"architect\": {\n ...\n }\n}\n</code-example>\n<p>You can also use the CLI <code>--baseHref</code> option with <a href=\"cli/build\" title=\"CLI reference for ng build\"><code>ng build</code></a> to declare the base <code>href</code> at compile time.</p>\n<h3 id=\"configuring-servers\">Configuring servers<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#configuring-servers\"><i class=\"material-icons\">link</i></a></h3>\n<p>Typical deployment of multiple languages serve each language from a different subdirectory.\nUsers are redirected to the preferred language defined in the browser using the\n<code>Accept-Language</code> HTTP header. If the user has not defined a preferred language,\nor if the preferred language is not available, then the server falls back to the default language.\nUsers can change the language by navigating to other subdirectories, which often occurs using a\nmenu implemented in the application.</p>\n<p>For more information on how to deploy apps to a remote server, see <a href=\"guide/deployment\" title=\"Deployment guide\">Deployment</a>.</p>\n<h4 id=\"nginx\">Nginx<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#nginx\"><i class=\"material-icons\">link</i></a></h4>\n<p>The following is an example of an Nginx configuration.</p>\n<code-example>\n<a href=\"api/common/http\" class=\"code-anchor\">http</a> {\n\n # Browser preferred language detection (does NOT require AcceptLanguageModule)\n map $http_accept_language $accept_language {\n ~*^de de;\n ~*^fr fr;\n ~*^en en;\n }\n # ...\n}\n\nserver {\n listen 80;\n server_name localhost;\n root /www/data;\n\n # Fallback to default language if no preference defined by <a href=\"api/animations/browser\" class=\"code-anchor\">browser</a>\n if ($accept_language ~ \"^$\") {\n set $accept_language \"fr\";\n }\n\n # Redirect \"/\" to Angular app in <a href=\"api/animations/browser\" class=\"code-anchor\">browser</a>'s preferred language\n rewrite ^/$ /$accept_language permanent;\n\n # Everything under the Angular app is always redirected to Angular in the correct language\n location ~ ^/(fr|de|en) {\n try_files $uri /$1/index.html?$args;\n }\n # ...\n}\n</code-example>\n<h4 id=\"apache\">Apache<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#apache\"><i class=\"material-icons\">link</i></a></h4>\n<p>The following is an example of an Apache configuration.</p>\n<code-example>\n<VirtualHost *:80>\n ServerName localhost\n DocumentRoot /www/data\n <Directory \"/www/data\">\n RewriteEngine on\n RewriteBase /\n RewriteRule ^../index\\.html$ - [L]\n\n RewriteCond %{REQUEST_FILENAME} !-f\n RewriteCond %{REQUEST_FILENAME} !-d\n RewriteRule (..) $1/index.html [L]\n\n RewriteCond %{HTTP:Accept-Language} ^de [NC]\n RewriteRule ^$ /de/ [R]\n\n RewriteCond %{HTTP:Accept-Language} ^en [NC]\n RewriteRule ^$ /en/ [R]\n\n RewriteCond %{HTTP:Accept-Language} !^en [NC]\n RewriteCond %{HTTP:Accept-Language} !^de [NC]\n RewriteRule ^$ /fr/ [R]\n </Directory>\n</VirtualHost>\n</code-example>\n<a id=\"app-pre-translation\"></a>\n<h2 id=\"explore-the-translated-example-app\">Explore the translated example app<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#explore-the-translated-example-app\"><i class=\"material-icons\">link</i></a></h2>\n<p>The following tabs show the example app and its translation files:</p>\n<code-tabs>\n <code-pane header=\"src/app/app.component.html\" path=\"i18n/src/app/app.component.html\">\n<h1 i18n=\"User welcome|An introduction header for this sample@@introductionHeader\">\n Hello i18n!\n</h1>\n\n<ng-container i18n>I don't output any element</ng-container>\n\n<br />\n\n<img [src]=\"logo\" i18n-title title=\"Angular logo\" />\n<br>\n<button (click)=\"inc(1)\">+</button> <button (click)=\"inc(-1)\">-</button>\n<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>\n({{minutes}})\n<br><br>\n<button (click)=\"male()\">&#9794;</button> <button (click)=\"female()\">&#9792;</button> <button (click)=\"other()\">&#9895;</button>\n<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>\n<br><br>\n<span i18n>Updated: {minutes, plural,\n =0 {just now}\n =1 {one minute ago}\n other {{{minutes}} minutes ago by {gender, select, male {male} female {female} other {other}}}}\n</span>\n\n\n</code-pane>\n <code-pane header=\"src/app/app.component.ts\" path=\"i18n/src/app/app.component.ts\">\nimport { <a href=\"api/core/Component\" class=\"code-anchor\">Component</a> } from '@angular/core';\n\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-root',\n templateUrl: './app.component.html'\n})\nexport class AppComponent {\n minutes = 0;\n gender = 'female';\n fly = true;\n logo = 'https://angular.io/assets/images/logos/angular/angular.png';\n inc(i: number) {\n this.minutes = Math.min(5, Math.max(0, this.minutes + i));\n }\n male() { this.gender = 'male'; }\n female() { this.gender = 'female'; }\n other() { this.gender = 'other'; }\n}\n\n\n\n</code-pane>\n <code-pane header=\"src/app/app.module.ts\" path=\"i18n/src/app/app.module.ts\">\nimport { <a href=\"api/core/NgModule\" class=\"code-anchor\">NgModule</a> } from '@angular/core';\nimport { <a href=\"api/platform-browser/BrowserModule\" class=\"code-anchor\">BrowserModule</a> } from '@angular/platform-browser';\n\nimport { AppComponent } from './app.component';\n\n@<a href=\"api/core/NgModule\" class=\"code-anchor\">NgModule</a>({\n imports: [ <a href=\"api/platform-browser/BrowserModule\" class=\"code-anchor\">BrowserModule</a> ],\n declarations: [ AppComponent ],\n bootstrap: [ AppComponent ]\n})\nexport class AppModule { }\n\n\n</code-pane>\n <code-pane header=\"src/main.ts\" path=\"i18n/doc-files/main.1.ts\">\nimport { <a href=\"api/core/enableProdMode\" class=\"code-anchor\">enableProdMode</a> } from '@angular/core';\nimport { <a href=\"api/platform-browser-dynamic/platformBrowserDynamic\" class=\"code-anchor\">platformBrowserDynamic</a> } from '@angular/platform-browser-dynamic';\n\nimport { AppModule } from './app/app.module';\nimport { environment } from './environments/environment';\n\nif (environment.production) {\n <a href=\"api/core/enableProdMode\" class=\"code-anchor\">enableProdMode</a>();\n}\n\n<a href=\"api/platform-browser-dynamic/platformBrowserDynamic\" class=\"code-anchor\">platformBrowserDynamic</a>().bootstrapModule(AppModule);\n\n\n</code-pane>\n <code-pane header=\"src/locale/messages.fr.xlf\" path=\"i18n/doc-files/messages.fr.xlf.html\">\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<xliff version=\"1.2\" xmlns=\"urn:oasis:names:tc:xliff:document:1.2\">\n <file source-language=\"en\" datatype=\"plaintext\" original=\"ng2.template\">\n <body>\n <trans-unit id=\"introductionHeader\" datatype=\"html\">\n <source>Hello i18n!</source>\n <note priority=\"1\" from=\"description\">An introduction header for this sample</note>\n <note priority=\"1\" from=\"meaning\">User welcome</note>\n </trans-unit>\n <trans-unit id=\"introductionHeader\" datatype=\"html\">\n <source>Hello i18n!</source>\n <target>Bonjour i18n !</target>\n <note priority=\"1\" from=\"description\">An introduction header for this sample</note>\n <note priority=\"1\" from=\"meaning\">User welcome</note>\n </trans-unit>\n <trans-unit id=\"ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3\" datatype=\"html\">\n <source>I don&apos;t output any element</source>\n <target>Je n'affiche aucun élément</target>\n </trans-unit>\n <trans-unit id=\"701174153757adf13e7c24a248c8a873ac9f5193\" datatype=\"html\">\n <source>Angular logo</source>\n <target>Logo d'Angular</target>\n </trans-unit>\n <trans-unit id=\"5a134dee893586d02bffc9611056b9cadf9abfad\" datatype=\"html\">\n <source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes ago} }</source>\n <target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes} }</target>\n </trans-unit>\n <trans-unit id=\"f99f34ac9bd4606345071bd813858dec29f3b7d1\" datatype=\"html\">\n <source>The author is <x id=\"ICU\" equiv-text=\"{gender, select, male {...} female {...} other {...}}\"/></source>\n <target>L'auteur est <x id=\"ICU\" equiv-text=\"{gender, select, male {...} female {...} other {...}}\"/></target>\n </trans-unit>\n <trans-unit id=\"eff74b75ab7364b6fa888f1cbfae901aaaf02295\" datatype=\"html\">\n <source>{VAR_SELECT, select, male {male} female {female} other {other} }</source>\n <target>{VAR_SELECT, select, male {un homme} female {une femme} other {autre} }</target>\n </trans-unit>\n <trans-unit id=\"972cb0cf3e442f7b1c00d7dab168ac08d6bdf20c\" datatype=\"html\">\n <source>Updated: <x id=\"ICU\" equiv-text=\"{minutes, plural, =0 {...} =1 {...} other {...}}\"/></source>\n <target>Mis à jour: <x id=\"ICU\" equiv-text=\"{minutes, plural, =0 {...} =1 {...} other {...}}\"/></target>\n </trans-unit>\n <trans-unit id=\"7151c2e67748b726f0864fc443861d45df21d706\" datatype=\"html\">\n <source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes ago by {VAR_SELECT, select, male {male} female {female} other {other} }} }</source>\n <target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id=\"INTERPOLATION\" equiv-text=\"{{minutes}}\"/> minutes par {VAR_SELECT, select, male {un homme} female {une femme} other {autre} }} }</target>\n </trans-unit>\n </body>\n </file>\n</xliff>\n\n\n\n</code-pane>\n</code-tabs>\n<h2 id=\"optional-practices\">Optional practices<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#optional-practices\"><i class=\"material-icons\">link</i></a></h2>\n<p>The following are optional practices that may be required in special cases:</p>\n<ul>\n<li><a href=\"guide/i18n#set-source-manually\">Set the source locale manually</a> by setting the <a href=\"api/core/LOCALE_ID\" title=\"API reference for LOCALE_ID\">LOCALE_ID</a> token.</li>\n<li><a href=\"guide/i18n#import-locale\">Import global variants of the locale data</a> for extra locale data.</li>\n<li><a href=\"guide/i18n#custom-id\">Manage marked text with custom IDs</a> if you require more control over matching translations.</li>\n</ul>\n<a id=\"set-source-manually\"></a>\n<h3 id=\"set-the-source-locale-manually\">Set the source locale manually<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#set-the-source-locale-manually\"><i class=\"material-icons\">link</i></a></h3>\n<p>Angular already contains locale data for <code>en-US</code>.\nThe Angular CLI automatically includes the locale data and sets the <code><a href=\"api/core/LOCALE_ID\" class=\"code-anchor\">LOCALE_ID</a></code> value when you use the <code>--localize</code> option with <a href=\"cli/build\" title=\"ng build description\"><code>ng build</code></a>.</p>\n<p>To manually set an app's source locale to one other than the automatic value, follow these steps:</p>\n<ol>\n<li>Look up the ID for the language-locale combination in <a href=\"https://github.com/angular/angular/tree/master/packages/common/locales\" title=\"Common locales in the Angular repository\">the Angular repository</a>.</li>\n<li>Set the <a href=\"api/core/LOCALE_ID\" title=\"API reference for LOCALE_ID\"><code>LOCALE_ID</code></a> token.\nThe following example sets the value of <code><a href=\"api/core/LOCALE_ID\" class=\"code-anchor\">LOCALE_ID</a></code> to <code>fr</code> (French):</li>\n</ol>\n<code-example path=\"i18n/doc-files/app.module.ts\" header=\"src/app/app.module.ts\">\nimport { <a href=\"api/core/LOCALE_ID\" class=\"code-anchor\">LOCALE_ID</a>, <a href=\"api/core/NgModule\" class=\"code-anchor\">NgModule</a> } from '@angular/core';\nimport { <a href=\"api/platform-browser/BrowserModule\" class=\"code-anchor\">BrowserModule</a> } from '@angular/platform-browser';\n\nimport { AppComponent } from '../src/app/app.component';\n\n@<a href=\"api/core/NgModule\" class=\"code-anchor\">NgModule</a>({\n imports: [ <a href=\"api/platform-browser/BrowserModule\" class=\"code-anchor\">BrowserModule</a> ],\n declarations: [ AppComponent ],\n providers: [ { provide: <a href=\"api/core/LOCALE_ID\" class=\"code-anchor\">LOCALE_ID</a>, useValue: 'fr' } ],\n bootstrap: [ AppComponent ]\n})\nexport class AppModule { }\n\n\n</code-example>\n<a id=\"import-locale\"></a>\n<h3 id=\"import-global-variants-of-the-locale-data\">Import global variants of the locale data<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#import-global-variants-of-the-locale-data\"><i class=\"material-icons\">link</i></a></h3>\n<p>Angular will automatically include locale data if you configure the locale using the <code>--localize</code> option with <a href=\"cli/build\" title=\"ng build description\"><code>ng build</code></a> CLI command.</p>\n<p>The <a href=\"https://github.com/angular/angular/tree/master/packages/common/locales\" title=\"Common locales in the Angular repository\">Angular repository</a> files (<code>@angular/common/locales</code>) contain most of the locale data that you need, but some advanced formatting options require additional locale data.\nGlobal variants of the locale data are available in <a href=\"https://github.com/angular/angular/tree/master/packages/common/locales/global\" title=\"Global locale variants in the Angular repository\"><code>@angular/common/locales/global</code></a>.\nThe following example imports the global variants for French (<code>fr</code>):</p>\n<code-example language=\"javascript\" header=\"app.module.ts\">\nimport '@angular/common/locales/<a href=\"api/core/global\" class=\"code-anchor\">global</a>/fr';\n</code-example>\n<a id=\"custom-id\"></a>\n<h3 id=\"manage-marked-text-with-custom-ids\">Manage marked text with custom IDs<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#manage-marked-text-with-custom-ids\"><i class=\"material-icons\">link</i></a></h3>\n<p>The Angular extractor generates a file with a translation unit entry for each <code>i18n</code>\nattribute in a template.\nAs described previously (in <a href=\"guide/i18n#transaction-unit-ids\">How meanings control text extraction and merging</a>), Angular assigns each translation unit a unique ID such as the following:</p>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" header=\"messages.fr.xlf.html\" region=\"generated-id\">\n<trans-unit id=\"ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3\" datatype=\"html\">\n\n</code-example>\n<p>When you change the translatable text, the extractor generates a new ID for that translation unit.\nIn most cases a text change would also require a change to the translation.\nTherefore, using a new ID keeps the text change in sync with translations.</p>\n<p>However, some translation systems require a specific form or syntax for the ID.\nTo address this requirement, you can mark text with <em>custom</em> IDs.\nWhile most developers don't need to use custom IDs, some may want to use IDs that have a unique syntax to convey additional metadata (such as the library, component, or area of the app in which the text appears).</p>\n<p>Specify a custom ID in the <code>i18n</code> attribute by using the prefix <code>@@</code>.\nThe following example defines the custom ID <code>introductionHeader</code>:</p>\n<code-example path=\"i18n/doc-files/app.component.html\" region=\"i18n-attribute-solo-id\" header=\"app/app.component.html\">\n<h1 i18n=\"@@introductionHeader\">Hello i18n!</h1>\n\n</code-example>\n<p>When you specify a custom ID, the extractor generates a translation unit with the custom ID:</p>\n<code-example path=\"i18n/doc-files/messages.fr.xlf.html\" header=\"messages.fr.xlf.html\" region=\"custom-id\">\n<trans-unit id=\"introductionHeader\" datatype=\"html\">\n\n</code-example>\n<p>If you change the text, the extractor does <em>not</em> change the ID.\nAs a result, you don't have to take the extra step of updating the translation.\nThe drawback of using custom IDs is that if you change the text, your translation may be out-of-sync with the newly changed source text.</p>\n<h4 id=\"use-a-custom-id-with-a-description\">Use a custom ID with a description<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#use-a-custom-id-with-a-description\"><i class=\"material-icons\">link</i></a></h4>\n<p>Use a custom ID in combination with a description and a meaning to further help the translator.\nThe following example includes a description, followed by the custom <code>id</code>:</p>\n<code-example path=\"i18n/doc-files/app.component.html\" region=\"i18n-attribute-id\" header=\"app/app.component.html\">\n<h1 i18n=\"An introduction header for this sample@@introductionHeader\">Hello i18n!</h1>\n\n</code-example>\n<p>The following example adds a meaning:</p>\n<code-example path=\"i18n/doc-files/app.component.html\" region=\"i18n-attribute-meaning-and-id\" header=\"app/app.component.html\">\n<h1 i18n=\"site header|An introduction header for this sample@@introductionHeader\">Hello i18n!</h1>\n\n</code-example>\n<h4 id=\"define-unique-custom-ids\">Define unique custom IDs<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/i18n#define-unique-custom-ids\"><i class=\"material-icons\">link</i></a></h4>\n<p>Be sure to define custom IDs that are unique.\nIf you use the same ID for two different text elements, the extraction tool extracts only the first one, and Angular uses its translation in place of both original text elements.</p>\n<p>For example, in the following code the same custom ID <code>myId</code> is defined for two different text elements:</p>\n<code-example language=\"html\">\n <h3 i18n=\"@@myId\">Hello</h3>\n <!-- ... -->\n <p i18n=\"@@myId\">Good bye</p>\n</code-example>\n<p>The following shows the translation to French:</p>\n<code-example language=\"xml\">\n <trans-unit id=\"myId\" datatype=\"html\">\n <source>Hello</source>\n <target <a href=\"api/animations/state\" class=\"code-anchor\">state</a>=\"new\">Bonjour</target>\n </trans-unit>\n</code-example>\n<p>Both elements now use the same translation (<code>Bonjour</code>) because they were defined with the same custom ID:</p>\n<code-example language=\"html\">\n <h3>Bonjour</h3>\n <!-- ... -->\n <p>Bonjour</p>\n</code-example>\n\n <div class=\"reviewed\">Last reviewed on Thu Apr 09 2020</div>\n</div>\n\n<!-- links to this doc:\n - api/common\n - api/common/CurrencyPipe\n - api/common/DatePipe\n - api/common/DecimalPipe\n - api/common/getLocaleExtraDayPeriodRules\n - api/common/getLocaleExtraDayPeriods\n - api/common/registerLocaleData\n - api/core/DEFAULT_CURRENCY_CODE\n - api/core/LOCALE_ID\n - api/core/MissingTranslationStrategy\n - api/core/TRANSLATIONS\n - api/core/TRANSLATIONS_FORMAT\n - api/localize/init/$localize\n - guide/angular-compiler-options\n - guide/architecture-next-steps\n - guide/ivy\n - guide/workspace-config\n-->\n<!-- links from this doc:\n - /api/common/DecimalPipe\n - /cli/build\n - api/animations/browser\n - api/animations/state\n - api/common/CurrencyPipe\n - api/common/DatePipe\n - api/common/PercentPipe\n - api/common/http\n - api/core/Component\n - api/core/LOCALE_ID\n - api/core/NgModule\n - api/core/enableProdMode\n - api/core/global\n - api/platform-browser-dynamic/platformBrowserDynamic\n - api/platform-browser/BrowserModule\n - cli\n - cli/build\n - guide/build\n - guide/deployment\n - guide/glossary#ahead-of-time-aot-compilation\n - guide/glossary#command-line-interface-cli\n - guide/glossary#component\n - guide/glossary#interpolation\n - guide/glossary#pipe\n - guide/glossary#template\n - guide/i18n#Template-translations\n - guide/i18n#add-helpful-descriptions-and-meanings\n - guide/i18n#add-the-localize-package\n - guide/i18n#apache\n - guide/i18n#app-pre-translation\n - guide/i18n#apply-specific-build-options-for-just-one-locale\n - guide/i18n#build-from-the-command-line\n - guide/i18n#change-the-source-language-file-format\n - guide/i18n#change-the-source-language-file-location\n - guide/i18n#change-the-source-language-file-name\n - guide/i18n#configuring-servers\n - guide/i18n#create-a-translation-file-for-each-language\n - guide/i18n#create-source\n - guide/i18n#custom-id\n - guide/i18n#define-locales-in-the-build-configuration\n - guide/i18n#define-unique-custom-ids\n - guide/i18n#deploy-locales\n - guide/i18n#deploy-multiple-locales\n - guide/i18n#explore-the-translated-example-app\n - guide/i18n#extract-the-source-language-file\n - guide/i18n#format-data-based-on-locale\n - guide/i18n#generate-app-versions-for-each-locale\n - guide/i18n#help-translator\n - guide/i18n#i18n-attribute\n - guide/i18n#i18n-pipes\n - guide/i18n#import-global-variants-of-the-locale-data\n - guide/i18n#import-locale\n - guide/i18n#localization-folder\n - guide/i18n#localize-build-command\n - guide/i18n#localize-build-one-locale\n - guide/i18n#localize-config\n - guide/i18n#localize-generate\n - guide/i18n#localizing-your-app\n - guide/i18n#manage-marked-text-with-custom-ids\n - guide/i18n#mark-alternates-and-nested-expressions\n - guide/i18n#mark-element-attributes-for-translations\n - guide/i18n#mark-plurals\n - guide/i18n#mark-plurals-and-alternates-for-translation\n - guide/i18n#mark-text-for-translations\n - guide/i18n#merge\n - guide/i18n#merge-translations-into-the-app\n - guide/i18n#ng-xi18n\n - guide/i18n#nginx\n - guide/i18n#no-element\n - guide/i18n#optional-practices\n - guide/i18n#plurals-alternates\n - guide/i18n#prepare-templates-for-translations\n - guide/i18n#prerequisites\n - guide/i18n#refer-to-locales-by-id\n - guide/i18n#report-missing-translations\n - guide/i18n#set-source-manually\n - guide/i18n#set-the-source-locale-manually\n - guide/i18n#setting-up-cli\n - guide/i18n#setting-up-locale\n - guide/i18n#steps-to-localize-your-app\n - guide/i18n#transaction-unit-ids\n - guide/i18n#translate-alternate-expressions\n - guide/i18n#translate-attributes\n - guide/i18n#translate-each-translation-file\n - guide/i18n#translate-nested-expressions\n - guide/i18n#translate-plural-select\n - guide/i18n#translate-plurals\n - guide/i18n#translate-plurals-and-alternate-expressions\n - guide/i18n#translate-text-nodes\n - guide/i18n#translate-text-not-for-display\n - guide/i18n#use-a-custom-id-with-a-description\n - guide/i18n#work-with-translation-files\n - guide/ivy#opting-out-of-ivy-in-version-9\n - guide/npm-packages\n - guide/workspace-config\n - http://cldr.unicode.org/core-spec#Unicode_Language_and_Locale_Identifiers\n - http://cldr.unicode.org/development/development-process/design-proposals/xmb\n - http://cldr.unicode.org/index/cldr-spec/plural-rules\n - http://cldr.unicode.org/index/cldr-spec/plural-rules#TOC-Choosing-Plural-Category-Names\n - http://userguide.icu-project.org/formatparse/messages\n - http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html\n - https://en.wikipedia.org/wiki/XLIFF\n - https://github.com/angular/angular/blob/ecffc3557fe1bff9718c01277498e877ca44588d/packages/core/src/i18n/locale_en.ts#L15-L18\n - https://github.com/angular/angular/edit/master/aio/content/guide/i18n.md?message=docs%3A%20describe%20your%20change...\n - https://github.com/angular/angular/tree/master/packages/common/locales\n - https://github.com/angular/angular/tree/master/packages/common/locales/global\n - https://marketfinder.thinkwithgoogle.com/intl/en_us/guide/how-to-approach-i18n/#overview\n - https://tools.ietf.org/html/bcp47\n - https://v8.angular.io/guide/i18n#merge-with-the-jit-compiler\n - https://www.loc.gov/standards/iso639-2/\n - https://www.w3.org/XML/\n-->"
|
|
} |