Online

Prepare component for translation

To prepare your project for translation, complete the following actions.

  • Use the i18n attribute to mark text in component templates
  • Use the i18n- attribute to mark attribute text strings in component templates
  • Use the $localize tagged message string to mark text strings in component code

Mark text in component template

In a component template, the i18n metadata is the value of the i18n attribute.

html
<element i18n="{i18n_metadata}">{string_to_translate}</element>

Use the i18n attribute to mark a static text message in your component templates for translation. Place it on every element tag that contains fixed text you want to translate.

i18n example

The following <h1> tag displays a simple English language greeting, "Hello i18n!".

app.component.html
<!--#docregion greeting-->
<h1>Hello i18n!</h1>
<!--#enddocregion greeting-->

<!--#docregion i18n-attribute-->
<h1 i18n>Hello i18n!</h1>
<!--#enddocregion i18n-attribute-->

<!--#docregion i18n-attribute-desc-->
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-desc-->

<!--#docregion i18n-attribute-meaning-->
<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-->

<!--#docregion i18n-attribute-id-->
<h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-id-->

<!--#docregion i18n-attribute-meaning-and-id-->
<h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-and-id-->

<!--#docregion i18n-attribute-solo-id-->
<h1 i18n="@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-solo-id-->

<!--#docregion i18n-title-->
<img [src]="logo" title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-->

<!--#docregion i18n-duplicate-custom-id-->
<h3 i18n="@@myId">Hello</h3>
<!-- ... -->
<p i18n="@@myId">Good bye</p>
<!--#enddocregion i18n-duplicate-custom-id-->

To mark the greeting for translation, add the i18n attribute to the <h1> tag.

app.component.html
<!--#docregion greeting-->
<h1>Hello i18n!</h1>
<!--#enddocregion greeting-->

<!--#docregion i18n-attribute-->
<h1 i18n>Hello i18n!</h1>
<!--#enddocregion i18n-attribute-->

<!--#docregion i18n-attribute-desc-->
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-desc-->

<!--#docregion i18n-attribute-meaning-->
<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-->

<!--#docregion i18n-attribute-id-->
<h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-id-->

<!--#docregion i18n-attribute-meaning-and-id-->
<h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-and-id-->

<!--#docregion i18n-attribute-solo-id-->
<h1 i18n="@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-solo-id-->

<!--#docregion i18n-title-->
<img [src]="logo" title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-->

<!--#docregion i18n-duplicate-custom-id-->
<h3 i18n="@@myId">Hello</h3>
<!-- ... -->
<p i18n="@@myId">Good bye</p>
<!--#enddocregion i18n-duplicate-custom-id-->

using conditional statement with i18n

The following <div> tag will display translated text as part of div and aria-label based on toggle status

html
<!--#docregion-->
<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>

<!--#docregion i18n-ng-container-->
<ng-container i18n>I don't output any element</ng-container>
<!--#enddocregion i18n-ng-container-->

<br />

<!--#docregion i18n-title-translate-->
<img [src]="logo" i18n-title title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-translate-->
<br />
<button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button>
<!--#docregion i18n-plural-->
<span i18n
  >Updated
  {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span
>
<!--#enddocregion i18n-plural-->
({{ minutes }}) <br /><br />
<button type="button" (click)="male()">&#9794;</button>
<button type="button" (click)="female()">&#9792;</button>
<button type="button" (click)="other()">&#9895;</button>
<!--#docregion i18n-select-->
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
<!--#enddocregion i18n-select-->
<br /><br />
<!--#docregion i18n-nested-->
<span i18n
  >Updated:
  {minutes, plural,
    =0 {just now}
    =1 {one minute ago}
    other {{{ minutes }} minutes ago by {gender, select, male {male} female {female} other {other}}}
  }
</span>
<!--#enddocregion i18n-nested-->
<br /><br />
<!--#docregion i18n-conditional-->
<button type="button" (click)="toggleDisplay()">Toggle</button>
<div i18n [attr.aria-label]="toggleAriaLabel()">{{ toggle() }}</div>
<!--#enddocregion i18n-conditional-->
ts
// #docregion
import {Component, computed, signal} from '@angular/core';
import {$localize} from '@angular/localize/init';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {
  minutes = 0;
  gender = 'female';
  fly = true;
  logo = '${this.baseUrl}/angular.svg';
  readonly toggle = signal(false);
  readonly toggleAriaLabel = computed(() => {
    return this.toggle()
      ? $localize`:Toggle Button|A button to toggle status:Show`
      : $localize`:Toggle Button|A button to toggle status:Hide`;
  });

  inc(i: number) {
    this.minutes = Math.min(5, Math.max(0, this.minutes + i));
  }
  male() {
    this.gender = 'male';
  }
  female() {
    this.gender = 'female';
  }
  other() {
    this.gender = 'other';
  }
  toggleDisplay() {
    this.toggle.update((toggle) => !toggle);
  }
}

Translate inline text without HTML element

Use the <ng-container> element to associate a translation behavior for specific text without changing the way text is displayed.

To avoid creating a new DOM element, wrap the text in an <ng-container> element. The following example shows the <ng-container> element transformed into a non-displayed HTML comment.

html
<!--#docregion-->
<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>

<!--#docregion i18n-ng-container-->
<ng-container i18n>I don't output any element</ng-container>
<!--#enddocregion i18n-ng-container-->

<br />

<!--#docregion i18n-title-translate-->
<img [src]="logo" i18n-title title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-translate-->
<br />
<button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button>
<!--#docregion i18n-plural-->
<span i18n
  >Updated
  {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span
>
<!--#enddocregion i18n-plural-->
({{ minutes }}) <br /><br />
<button type="button" (click)="male()">&#9794;</button>
<button type="button" (click)="female()">&#9792;</button>
<button type="button" (click)="other()">&#9895;</button>
<!--#docregion i18n-select-->
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
<!--#enddocregion i18n-select-->
<br /><br />
<!--#docregion i18n-nested-->
<span i18n
  >Updated:
  {minutes, plural,
    =0 {just now}
    =1 {one minute ago}
    other {{{ minutes }} minutes ago by {gender, select, male {male} female {female} other {other}}}
  }
</span>
<!--#enddocregion i18n-nested-->
<br /><br />
<!--#docregion i18n-conditional-->
<button type="button" (click)="toggleDisplay()">Toggle</button>
<div i18n [attr.aria-label]="toggleAriaLabel()">{{ toggle() }}</div>
<!--#enddocregion i18n-conditional-->

Name the interpolation placeholder

By default, Angular generates a placeholder name for each interpolation in a translated message. To give it a meaningful name that helps translators understand the context, add an //i18n(ph="name") comment inside the interpolation.

html
<element i18n>{{ expression //i18n(ph="placeholder_name") }}</element>

For example:

html
<p i18n>Hello, {{ username //i18n(ph="name") }}!</p>

This is the template equivalent of naming a placeholder in component code with [$localize][ApiLocalizeInitLocalize]:

ts
$localize`Hello, ${username}:name:!`;

Mark element attributes for translations

In a component template, the i18n metadata is the value of the i18n-{attribute_name} attribute.

html
<element i18n-{attribute_name}="{i18n_metadata}" {attribute_name}="{attribute_value}" />

The attributes of HTML elements include text that should be translated along with the rest of the displayed text in the component template.

Use i18n-{attributename} with any attribute of any element and replace {attributename} with the name of the attribute. Use the following syntax to assign a meaning, description, and custom ID.

html
i18n-{attribute_name}="{meaning}|{description}@@{id}"

i18n-title example

To translate the title of an image, review this example. The following example displays an image with a title attribute.

app.component.html
<!--#docregion greeting-->
<h1>Hello i18n!</h1>
<!--#enddocregion greeting-->

<!--#docregion i18n-attribute-->
<h1 i18n>Hello i18n!</h1>
<!--#enddocregion i18n-attribute-->

<!--#docregion i18n-attribute-desc-->
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-desc-->

<!--#docregion i18n-attribute-meaning-->
<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-->

<!--#docregion i18n-attribute-id-->
<h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-id-->

<!--#docregion i18n-attribute-meaning-and-id-->
<h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-and-id-->

<!--#docregion i18n-attribute-solo-id-->
<h1 i18n="@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-solo-id-->

<!--#docregion i18n-title-->
<img [src]="logo" title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-->

<!--#docregion i18n-duplicate-custom-id-->
<h3 i18n="@@myId">Hello</h3>
<!-- ... -->
<p i18n="@@myId">Good bye</p>
<!--#enddocregion i18n-duplicate-custom-id-->

To mark the title attribute for translation, complete the following action.

Add the i18n-title attribute

The following example displays how to mark the title attribute on the img tag by adding i18n-title.

app.component.html
<!--#docregion-->
<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>

<!--#docregion i18n-ng-container-->
<ng-container i18n>I don't output any element</ng-container>
<!--#enddocregion i18n-ng-container-->

<br />

<!--#docregion i18n-title-translate-->
<img [src]="logo" i18n-title title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-translate-->
<br />
<button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button>
<!--#docregion i18n-plural-->
<span i18n
  >Updated
  {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span
>
<!--#enddocregion i18n-plural-->
({{ minutes }}) <br /><br />
<button type="button" (click)="male()">&#9794;</button>
<button type="button" (click)="female()">&#9792;</button>
<button type="button" (click)="other()">&#9895;</button>
<!--#docregion i18n-select-->
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
<!--#enddocregion i18n-select-->
<br /><br />
<!--#docregion i18n-nested-->
<span i18n
  >Updated:
  {minutes, plural,
    =0 {just now}
    =1 {one minute ago}
    other {{{ minutes }} minutes ago by {gender, select, male {male} female {female} other {other}}}
  }
</span>
<!--#enddocregion i18n-nested-->
<br /><br />
<!--#docregion i18n-conditional-->
<button type="button" (click)="toggleDisplay()">Toggle</button>
<div i18n [attr.aria-label]="toggleAriaLabel()">{{ toggle() }}</div>
<!--#enddocregion i18n-conditional-->

Mark text in component code

In component code, the translation source text and the metadata are surrounded by backtick \(<code>&#96;</code>\) characters.

Use the [$localize][ApiLocalizeInitLocalize] tagged message string to mark a string in your code for translation.

ts
$localize`string_to_translate`;

The i18n metadata is surrounded by colon \(:\) characters and prepends the translation source text.

ts
$localize`:{i18n_metadata}:string_to_translate`;

Include interpolated text

Include interpolations in a [$localize][ApiLocalizeInitLocalize] tagged message string.

ts
$localize`string_to_translate ${variable_name}`;

Name the interpolation placeholder

ts
$localize`string_to_translate ${variable_name}:placeholder_name:`;

Conditional syntax for translations

ts
return this.show ? $localize`Show Tabs` : $localize`Hide tabs`;

i18n metadata for translation

html
{meaning}|{description}@@{custom_id}

The following parameters provide context and additional information to reduce confusion for your translator.

Metadata parameterDetails
Custom IDProvide a custom identifier
DescriptionProvide additional information or context
MeaningProvide the meaning or intent of the text within the specific context

For additional information about custom IDs, see [Manage marked text with custom IDs][GuideI18nOptionalManageMarkedText].

Add helpful descriptions and meanings

To translate a text message accurately, provide additional information or context for the translator.

Add a description of the text message as the value of the i18n attribute or [$localize][ApiLocalizeInitLocalize] tagged message string.

The following example shows the value of the i18n attribute.

app.component.html
<!--#docregion greeting-->
<h1>Hello i18n!</h1>
<!--#enddocregion greeting-->

<!--#docregion i18n-attribute-->
<h1 i18n>Hello i18n!</h1>
<!--#enddocregion i18n-attribute-->

<!--#docregion i18n-attribute-desc-->
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-desc-->

<!--#docregion i18n-attribute-meaning-->
<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-->

<!--#docregion i18n-attribute-id-->
<h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-id-->

<!--#docregion i18n-attribute-meaning-and-id-->
<h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-and-id-->

<!--#docregion i18n-attribute-solo-id-->
<h1 i18n="@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-solo-id-->

<!--#docregion i18n-title-->
<img [src]="logo" title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-->

<!--#docregion i18n-duplicate-custom-id-->
<h3 i18n="@@myId">Hello</h3>
<!-- ... -->
<p i18n="@@myId">Good bye</p>
<!--#enddocregion i18n-duplicate-custom-id-->

The following example shows the value of the [$localize][ApiLocalizeInitLocalize] tagged message string with a description.

ts
$localize`:An introduction header for this sample:Hello i18n!`;

The translator may also need to know the meaning or intent of the text message within this particular application context, in order to translate it the same way as other text with the same meaning. Start the i18n attribute value with the meaning and separate it from the description with the | character: {meaning}|{description}.

h1 example

For example, you may want to specify that the <h1> tag is a site header that you need translated the same way, whether it is used as a header or referenced in another section of text.

The following example shows how to specify that the <h1> tag must be translated as a header or referenced elsewhere.

app.component.html
<!--#docregion greeting-->
<h1>Hello i18n!</h1>
<!--#enddocregion greeting-->

<!--#docregion i18n-attribute-->
<h1 i18n>Hello i18n!</h1>
<!--#enddocregion i18n-attribute-->

<!--#docregion i18n-attribute-desc-->
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-desc-->

<!--#docregion i18n-attribute-meaning-->
<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-->

<!--#docregion i18n-attribute-id-->
<h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-id-->

<!--#docregion i18n-attribute-meaning-and-id-->
<h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-meaning-and-id-->

<!--#docregion i18n-attribute-solo-id-->
<h1 i18n="@@introductionHeader">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-solo-id-->

<!--#docregion i18n-title-->
<img [src]="logo" title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-->

<!--#docregion i18n-duplicate-custom-id-->
<h3 i18n="@@myId">Hello</h3>
<!-- ... -->
<p i18n="@@myId">Good bye</p>
<!--#enddocregion i18n-duplicate-custom-id-->

The result is any text marked with site header, as the meaning is translated exactly the same way.

The following code example shows the value of the [$localize][ApiLocalizeInitLocalize] tagged message string with a meaning and a description.

ts
$localize`:site header|An introduction header for this sample:Hello i18n!`;

ICU expressions

ICU expressions help you mark alternate text in component templates to meet conditions. An ICU expression includes a component property, an ICU clause, and the case statements surrounded by open curly brace \({\) and close curly brace \(}\) characters.

html
{ component_property, icu_clause, case_statements }

The component property defines the variable. An ICU clause defines the type of conditional text.

ICU clauseDetails
[plural][GuideI18nCommonPrepareMarkPlurals]Mark the use of plural numbers
[select][GuideI18nCommonPrepareMarkAlternatesAndNestedExpressions]Mark choices for alternate text based on your defined string values

To simplify translation, use International Components for Unicode clauses \(ICU clauses\) with regular expressions.

Mark plurals

Different languages have different pluralization rules that increase the difficulty of translation. Because other locales express cardinality differently, you may need to set pluralization categories that do not align with English. Use the plural clause to mark expressions that may not be meaningful if translated word-for-word.

html
{ component_property, plural, pluralization_categories }

After the pluralization category, enter the default text \(English\) surrounded by open curly brace \({\) and close curly brace \(}\) characters.

html
pluralization_category { }

The following pluralization categories are available for English and may change based on the locale.

Pluralization categoryDetailsExample
zeroQuantity is zero=0 { }
zero { }
oneQuantity is 1=1 { }
one { }
twoQuantity is 2=2 { }
two { }
fewQuantity is 2 or morefew { }
manyQuantity is a large numbermany { }
otherThe default quantityother { }

If none of the pluralization categories match, Angular uses other to match the standard fallback for a missing category.

html
other { default_quantity }

minutes example

If you want to display the following phrase in English, where x is a number.

html
updated x minutes ago

And you also want to display the following phrases based on the cardinality of x.

html
updated just now
html
updated one minute ago

Use HTML markup and interpolations. The following code example shows how to use the plural clause to express the previous three situations in a <span> element.

app.component.html
<!--#docregion-->
<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>

<!--#docregion i18n-ng-container-->
<ng-container i18n>I don't output any element</ng-container>
<!--#enddocregion i18n-ng-container-->

<br />

<!--#docregion i18n-title-translate-->
<img [src]="logo" i18n-title title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-translate-->
<br />
<button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button>
<!--#docregion i18n-plural-->
<span i18n
  >Updated
  {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span
>
<!--#enddocregion i18n-plural-->
({{ minutes }}) <br /><br />
<button type="button" (click)="male()">&#9794;</button>
<button type="button" (click)="female()">&#9792;</button>
<button type="button" (click)="other()">&#9895;</button>
<!--#docregion i18n-select-->
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
<!--#enddocregion i18n-select-->
<br /><br />
<!--#docregion i18n-nested-->
<span i18n
  >Updated:
  {minutes, plural,
    =0 {just now}
    =1 {one minute ago}
    other {{{ minutes }} minutes ago by {gender, select, male {male} female {female} other {other}}}
  }
</span>
<!--#enddocregion i18n-nested-->
<br /><br />
<!--#docregion i18n-conditional-->
<button type="button" (click)="toggleDisplay()">Toggle</button>
<div i18n [attr.aria-label]="toggleAriaLabel()">{{ toggle() }}</div>
<!--#enddocregion i18n-conditional-->

Review the following details in the previous code example.

ParametersDetails
minutesThe first parameter specifies the component property is minutes and determines the number of minutes.
pluralThe second parameter specifies the ICU clause is plural.
=0 {just now}For zero minutes, the pluralization category is =0. The value is just now.
=1 {one minute}For one minute, the pluralization category is =1. The value is one minute.
other {{{minutes}} minutes ago}For any unmatched cardinality, the default pluralization category is other. The value is {{minutes}} minutes ago.

{{minutes}} is an interpolation.

Mark alternates and nested expressions

The select clause marks choices for alternate text based on your defined string values.

html
{ component_property, select, selection_categories }

Translate all of the alternates to display alternate text based on the value of a variable.

After the selection category, enter the text \(English\) surrounded by open curly brace \({\) and close curly brace \(}\) characters.

html
selection_category { text }

Different locales have different grammatical constructions that increase the difficulty of translation. Use HTML markup. If none of the selection categories match, Angular uses other to match the standard fallback for a missing category.

html
other { default_value }

gender example

If you want to display the following phrase in English.

html
The author is other

And you also want to display the following phrases based on the gender property of the component.

html
The author is female
html
The author is male

The following code example shows how to bind the gender property of the component and use the select clause to express the previous three situations in a <span> element.

The gender property binds the outputs to each of following string values.

ValueEnglish value
femalefemale
malemale
otherother

The select clause maps the values to the appropriate translations. The following code example shows gender property used with the select clause.

app.component.html
<!--#docregion-->
<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>

<!--#docregion i18n-ng-container-->
<ng-container i18n>I don't output any element</ng-container>
<!--#enddocregion i18n-ng-container-->

<br />

<!--#docregion i18n-title-translate-->
<img [src]="logo" i18n-title title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-translate-->
<br />
<button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button>
<!--#docregion i18n-plural-->
<span i18n
  >Updated
  {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span
>
<!--#enddocregion i18n-plural-->
({{ minutes }}) <br /><br />
<button type="button" (click)="male()">&#9794;</button>
<button type="button" (click)="female()">&#9792;</button>
<button type="button" (click)="other()">&#9895;</button>
<!--#docregion i18n-select-->
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
<!--#enddocregion i18n-select-->
<br /><br />
<!--#docregion i18n-nested-->
<span i18n
  >Updated:
  {minutes, plural,
    =0 {just now}
    =1 {one minute ago}
    other {{{ minutes }} minutes ago by {gender, select, male {male} female {female} other {other}}}
  }
</span>
<!--#enddocregion i18n-nested-->
<br /><br />
<!--#docregion i18n-conditional-->
<button type="button" (click)="toggleDisplay()">Toggle</button>
<div i18n [attr.aria-label]="toggleAriaLabel()">{{ toggle() }}</div>
<!--#enddocregion i18n-conditional-->

gender and minutes example

Combine different clauses together, such as the plural and select clauses. The following code example shows nested clauses based on the gender and minutes examples.

app.component.html
<!--#docregion-->
<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>

<!--#docregion i18n-ng-container-->
<ng-container i18n>I don't output any element</ng-container>
<!--#enddocregion i18n-ng-container-->

<br />

<!--#docregion i18n-title-translate-->
<img [src]="logo" i18n-title title="Angular logo" alt="Angular logo" />
<!--#enddocregion i18n-title-translate-->
<br />
<button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button>
<!--#docregion i18n-plural-->
<span i18n
  >Updated
  {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span
>
<!--#enddocregion i18n-plural-->
({{ minutes }}) <br /><br />
<button type="button" (click)="male()">&#9794;</button>
<button type="button" (click)="female()">&#9792;</button>
<button type="button" (click)="other()">&#9895;</button>
<!--#docregion i18n-select-->
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
<!--#enddocregion i18n-select-->
<br /><br />
<!--#docregion i18n-nested-->
<span i18n
  >Updated:
  {minutes, plural,
    =0 {just now}
    =1 {one minute ago}
    other {{{ minutes }} minutes ago by {gender, select, male {male} female {female} other {other}}}
  }
</span>
<!--#enddocregion i18n-nested-->
<br /><br />
<!--#docregion i18n-conditional-->
<button type="button" (click)="toggleDisplay()">Toggle</button>
<div i18n [attr.aria-label]="toggleAriaLabel()">{{ toggle() }}</div>
<!--#enddocregion i18n-conditional-->

What's next

[ApiLocalizeInitLocalize]: api/localize/init/$localize '$localize | init - localize - API | Angular' [GuideI18nCommonPrepareMarkAlternatesAndNestedExpressions]: guide/i18n/prepare#mark-alternates-and-nested-expressions 'Mark alternates and nested expressions - Prepare templates for translation | Angular' [GuideI18nCommonPrepareMarkPlurals]: guide/i18n/prepare#mark-plurals 'Mark plurals - Prepare component for translation | Angular' [GuideI18nOptionalManageMarkedText]: guide/i18n/manage-marked-text 'Manage marked text with custom IDs | Angular' [GithubAngularAngularBlobEcffc3557fe1bff9718c01277498e877ca44588dPackagesCoreSrcI18nLocaleEnTsL14L18]: https://github.com/angular/angular/blob/ecffc3557fe1bff9718c01277498e877ca44588d/packages/core/src/i18n/localeen.ts#L14-L18 'Line 14 to 18 - angular/packages/core/src/i18n/localeen.ts | angular/angular | GitHub' [GithubUnicodeOrgIcuUserguideFormatParseMessages]: https://unicode-org.github.io/icu/userguide/format_parse/messages 'ICU Message Format - ICU Documentation | Unicode | GitHub' [UnicodeCldrMain]: https://cldr.unicode.org 'Unicode CLDR Project' [UnicodeCldrIndexCldrSpecPluralRules]: http://cldr.unicode.org/index/cldr-spec/plural-rules 'Plural Rules | CLDR - Unicode Common Locale Data Repository | Unicode' [UnicodeCldrIndexCldrSpecPluralRulesTocChoosingPluralCategoryNames]: http://cldr.unicode.org/index/cldr-spec/plural-rules#TOC-Choosing-Plural-Category-Names 'Choosing Plural Category Names - Plural Rules | CLDR - Unicode Common Locale Data Repository | Unicode'