Guías Detalladas
Internacionalización

Preparar un componente para traducción

Para preparar tu proyecto para traducción, completa las siguientes acciones.

  • Usa el atributo i18n para marcar texto en plantillas de componentes
  • Usa el atributo i18n- para marcar cadenas de texto de atributos en plantillas de componentes
  • Usa la cadena de mensaje etiquetada $localize para marcar cadenas de texto en código de componentes

Marcar texto en la plantilla del componente

En una plantilla de componente, los metadatos i18n son el valor del atributo i18n.

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

Usa el atributo i18n para marcar un mensaje de texto estático en tus plantillas de componentes para traducción. Colócalo en cada etiqueta de elemento que contenga texto fijo que quieras traducir.

ÚTIL: El atributo i18n es un atributo personalizado que las herramientas y compiladores de Angular reconocen.

Ejemplo de i18n

La siguiente etiqueta <h1> muestra un saludo simple en inglés, "Hello i18n!".

src/app/app.component.html

<h1>Hello i18n!</h1><h1 i18n>Hello i18n!</h1><h1 i18n="An introduction header for this sample">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1><h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="@@introductionHeader">Hello i18n!</h1><img [src]="logo" title="Angular logo" alt="Angular logo"><h3 i18n="@@myId">Hello</h3><!-- ... --><p i18n="@@myId">Good bye</p>

Para marcar el saludo para traducción, agrega el atributo i18n a la etiqueta <h1>.

src/app/app.component.html

<h1>Hello i18n!</h1><h1 i18n>Hello i18n!</h1><h1 i18n="An introduction header for this sample">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1><h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="@@introductionHeader">Hello i18n!</h1><img [src]="logo" title="Angular logo" alt="Angular logo"><h3 i18n="@@myId">Hello</h3><!-- ... --><p i18n="@@myId">Good bye</p>

Usando la declaración condicional con i18n

La siguiente etiqueta <div> mostrará texto traducido como parte de div y aria-label según el estado del interruptor (toggle).

src/app/app.component.html

<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">  Hello i18n!</h1><ng-container i18n>I don't output any element</ng-container><br /><img [src]="logo" i18n-title title="Angular logo" alt="Angular logo"/><br><button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button><span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span>({{ minutes }})<br><br><button type="button" (click)="male()">♂</button><button type="button" (click)="female()">♀</button><button type="button" (click)="other()">⚧</button><span i18n>The author is {gender, select, male {male} female {female} other {other}}</span><br><br><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><br><br><button type="button" (click)="toggleDisplay()">Toggle</button><div i18n [attr.aria-label]="toggleAriaLabel()">{{toggle()}}</div>

src/app/app.component.ts

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);  }}

Traducir texto en línea sin un elemento HTML

Usa el elemento <ng-container> para asociar un comportamiento de traducción para texto específico sin cambiar la forma en que se muestra el texto.

ÚTIL: Cada elemento HTML crea un nuevo elemento DOM. Para evitar crear un nuevo elemento DOM, envuelve el texto en un elemento <ng-container>. El siguiente ejemplo muestra el elemento <ng-container> transformado en un comentario HTML no visible.

<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">  Hello i18n!</h1><ng-container i18n>I don't output any element</ng-container><br /><img [src]="logo" i18n-title title="Angular logo" alt="Angular logo"/><br><button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button><span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span>({{ minutes }})<br><br><button type="button" (click)="male()">♂</button><button type="button" (click)="female()">♀</button><button type="button" (click)="other()">⚧</button><span i18n>The author is {gender, select, male {male} female {female} other {other}}</span><br><br><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><br><br><button type="button" (click)="toggleDisplay()">Toggle</button><div i18n [attr.aria-label]="toggleAriaLabel()">{{toggle()}}</div>

Marcar atributos de elementos para traducción

En una plantilla de componente, los metadatos i18n son el valor del atributo i18n-{attribute_name}.

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

Los atributos de elementos HTML incluyen texto que debe traducirse junto con el resto del texto mostrado en la plantilla del componente.

Usa i18n-{attribute_name} con cualquier atributo de cualquier elemento y reemplaza {attribute_name} con el nombre del atributo. Usa la siguiente sintaxis para asignar un significado, descripción e ID personalizado.

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

Ejemplo de i18n-title

Para traducir el título de una imagen, revisa este ejemplo. El siguiente ejemplo muestra una imagen con un atributo title.

src/app/app.component.html

<h1>Hello i18n!</h1><h1 i18n>Hello i18n!</h1><h1 i18n="An introduction header for this sample">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1><h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="@@introductionHeader">Hello i18n!</h1><img [src]="logo" title="Angular logo" alt="Angular logo"><h3 i18n="@@myId">Hello</h3><!-- ... --><p i18n="@@myId">Good bye</p>

Para marcar el atributo title para traducción, completa la siguiente acción.

  1. Agrega el atributo i18n-title

    El siguiente ejemplo muestra cómo marcar el atributo title en la etiqueta img agregando i18n-title.

    src/app/app.component.html

    <h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">  Hello i18n!</h1><ng-container i18n>I don't output any element</ng-container><br /><img [src]="logo" i18n-title title="Angular logo" alt="Angular logo"/><br><button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button><span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span>({{ minutes }})<br><br><button type="button" (click)="male()">♂</button><button type="button" (click)="female()">♀</button><button type="button" (click)="other()">⚧</button><span i18n>The author is {gender, select, male {male} female {female} other {other}}</span><br><br><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><br><br><button type="button" (click)="toggleDisplay()">Toggle</button><div i18n [attr.aria-label]="toggleAriaLabel()">{{toggle()}}</div>

Marcar texto en el código del componente

En el código del componente, el texto fuente de traducción y los metadatos están rodeados por caracteres de acento grave (`).

Usa la cadena de mensaje etiquetada $localize para marcar una cadena en tu código para traducción.

$localize`string_to_translate`;

Los metadatos i18n están rodeados por caracteres de dos puntos (:) y preceden al texto fuente de traducción.

$localize`:{i18n_metadata}:string_to_translate`

Incluir texto interpolado

Incluye interpolaciones en una cadena de mensaje etiquetada $localize.

$localize`string_to_translate ${variable_name}`;

Nombrar el marcador de posición (placeholder) de la interpolación

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

Sintaxis condicional para traducciones

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

Metadatos i18n para traducción

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

Los siguientes parámetros proporcionan contexto e información adicional para reducir la confusión de tu traductor.

Parámetro de metadatos Detalles
ID personalizado Proporciona un identificador personalizado
Descripción Proporciona información adicional o contexto
Significado Proporciona el significado o intención del texto dentro del contexto específico

Para información adicional sobre IDs personalizados, consulta Gestionar texto marcado con IDs personalizados.

Agregar descripciones y significados útiles

Para traducir un mensaje de texto con precisión, proporciona información adicional o contexto para el traductor.

Agrega una descripción del mensaje de texto como valor del atributo i18n o cadena de mensaje etiquetada $localize.

El siguiente ejemplo muestra el valor del atributo i18n.

src/app/app.component.html

<h1>Hello i18n!</h1><h1 i18n>Hello i18n!</h1><h1 i18n="An introduction header for this sample">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1><h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="@@introductionHeader">Hello i18n!</h1><img [src]="logo" title="Angular logo" alt="Angular logo"><h3 i18n="@@myId">Hello</h3><!-- ... --><p i18n="@@myId">Good bye</p>

El siguiente ejemplo muestra el valor de la cadena de mensaje etiquetada $localize con una descripción.

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

El traductor también puede necesitar conocer el significado o intención del mensaje de texto dentro de este contexto particular de la aplicación, para traducirlo de la misma manera que otro texto con el mismo significado. Comienza el valor del atributo i18n con el significado y sepáralo de la descripción con el carácter |: {meaning}|{description}.

Ejemplo de h1

Por ejemplo, puedes querer especificar que la etiqueta <h1> es un encabezado de sitio que necesitas traducir de la misma manera, ya sea que se use como encabezado o se haga referencia en otra sección del texto.

El siguiente ejemplo muestra cómo especificar que la etiqueta <h1> debe traducirse como un encabezado o referenciarse en otro lugar.

src/app/app.component.html

<h1>Hello i18n!</h1><h1 i18n>Hello i18n!</h1><h1 i18n="An introduction header for this sample">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1><h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1><h1 i18n="@@introductionHeader">Hello i18n!</h1><img [src]="logo" title="Angular logo" alt="Angular logo"><h3 i18n="@@myId">Hello</h3><!-- ... --><p i18n="@@myId">Good bye</p>

El resultado es que cualquier texto marcado con site header, como significado, se traduce exactamente de la misma manera.

El siguiente ejemplo de código muestra el valor de la cadena de mensaje etiquetada $localize con un significado y una descripción.

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

Cómo los significados controlan la extracción y fusión de texto

La herramienta de extracción de Angular genera una entrada de unidad de traducción para cada atributo i18n en una plantilla. La herramienta de extracción de Angular asigna a cada unidad de traducción un ID único basado en el significado y la descripción.

ÚTIL: Para más información sobre la herramienta de extracción de Angular, consulta Trabajar con archivos de traducción.

Los mismos elementos de texto con diferentes significados se extraen con IDs diferentes. Por ejemplo, si la palabra "right" usa las siguientes dos definiciones en dos ubicaciones diferentes, la palabra se traduce de manera diferente y se fusiona de nuevo en la aplicación como entradas de traducción diferentes.

  • correct como en "you are right" (estás en lo correcto)
  • direction como en "turn right" (gira a la derecha)

Si los mismos elementos de texto cumplen las siguientes condiciones, los elementos de texto se extraen solo una vez y usan el mismo ID.

  • Mismo significado o definición
  • Diferentes descripciones

Esa única entrada de traducción se fusiona de nuevo en la aplicación dondequiera que aparezcan los mismos elementos de texto.

Expresiones ICU

Las expresiones ICU te ayudan a marcar texto alternativo en plantillas de componentes para cumplir condiciones. Una expresión ICU incluye una propiedad del componente, una cláusula ICU y las declaraciones de caso rodeadas por caracteres de llave de apertura ({) y llave de cierre (}).

{ component_property, icu_clause, case_statements }

La propiedad del componente define la variable. Una cláusula ICU define el tipo de texto condicional.

Cláusula ICU Detalles
plural Marca el uso de números plurales
select Marca opciones para texto alternativo basado en tus valores de cadena definidos

Para simplificar la traducción, usa cláusulas de Componentes Internacionales para Unicode (cláusulas ICU) con expresiones regulares.

ÚTIL: Las cláusulas ICU se adhieren al Formato de Mensaje ICU especificado en las reglas de pluralización CLDR.

Marcar plurales

Diferentes idiomas tienen diferentes reglas de pluralización que aumentan la dificultad de traducción. Debido a que otras configuraciones regionales expresan la cardinalidad de manera diferente, puedes necesitar establecer categorías de pluralización que no se alineen con el inglés. Usa la cláusula plural para marcar expresiones que pueden no ser significativas si se traducen palabra por palabra.

{ component_property, plural, pluralization_categories }

Después de la categoría de pluralización, ingresa el texto predeterminado (inglés) rodeado por caracteres de llave de apertura ({) y llave de cierre (}).

pluralization_category { }

Las siguientes categorías de pluralización están disponibles para inglés y pueden cambiar según la configuración regional.

Categoría de pluralización Detalles Ejemplo
zero La cantidad es cero =0 { }
zero { }
one La cantidad es 1 =1 { }
one { }
two La cantidad es 2 =2 { }
two { }
few La cantidad es 2 o más few { }
many La cantidad es un número grande many { }
other La cantidad predeterminada other { }

Si ninguna de las categorías de pluralización coincide, Angular usa other para coincidir con la opción de respaldo estándar para una categoría faltante.

other { default_quantity }

ÚTIL: Para más información sobre categorías de pluralización, consulta Elegir nombres de categorías plurales en CLDR - Repositorio Común de Datos de Configuración Regional Unicode.

Muchas configuraciones regionales no soportan algunas de las categorías de pluralización. La configuración regional predeterminada (en-US) usa una función plural() muy simple que no soporta la categoría de pluralización few. Otra configuración regional con una función plural() simple es es. El siguiente ejemplo de código muestra la función plural() de en-US.

function plural(n: number): number {  let i = Math.floor(Math.abs(n)),    v = n.toString().replace(/^[^.]*\.?/, '').length;  if (i === 1 && v === 0) return 1;  return 5;}

La función plural() solo retorna 1 (one) o 5 (other). La categoría few nunca coincide.

Ejemplo de minutes

Si quieres mostrar la siguiente frase en inglés, donde x es un número.

updated x minutes ago

Y también quieres mostrar las siguientes frases según la cardinalidad de x.

updated just now
updated one minute ago

Usa marcado HTML e interpolaciones. El siguiente ejemplo de código muestra cómo usar la cláusula plural para expresar las tres situaciones anteriores en un elemento <span>.

src/app/app.component.html

<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">  Hello i18n!</h1><ng-container i18n>I don't output any element</ng-container><br /><img [src]="logo" i18n-title title="Angular logo" alt="Angular logo"/><br><button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button><span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span>({{ minutes }})<br><br><button type="button" (click)="male()">♂</button><button type="button" (click)="female()">♀</button><button type="button" (click)="other()">⚧</button><span i18n>The author is {gender, select, male {male} female {female} other {other}}</span><br><br><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><br><br><button type="button" (click)="toggleDisplay()">Toggle</button><div i18n [attr.aria-label]="toggleAriaLabel()">{{toggle()}}</div>

Revisa los siguientes detalles en el ejemplo de código anterior.

Parámetros Detalles
minutes El primer parámetro especifica que la propiedad del componente es minutes y determina el número de minutos.
plural El segundo parámetro especifica que la cláusula ICU es plural.
=0 {just now} Para cero minutos, la categoría de pluralización es =0. El valor es just now.
=1 {one minute} Para un minuto, la categoría de pluralización es =1. El valor es one minute.
other {{{minutes}} minutes ago} Para cualquier cardinalidad no coincidente, la categoría de pluralización predeterminada es other. El valor es {{minutes}} minutes ago.

{{minutes}} es una interpolación.

Marcar alternativas y expresiones anidadas

La cláusula select marca opciones para texto alternativo basado en tus valores de cadena definidos.

{ component_property, select, selection_categories }

Traduce todas las alternativas para mostrar texto alternativo basado en el valor de una variable.

Después de la categoría de selección, ingresa el texto (inglés) rodeado por caracteres de llave de apertura ({) y llave de cierre (}).

selection_category { text }

Diferentes configuraciones regionales tienen diferentes construcciones gramaticales que aumentan la dificultad de traducción. Usa marcado HTML. Si ninguna de las categorías de selección coincide, Angular usa other para coincidir con la opción de respaldo estándar para una categoría faltante.

other { default_value }

Ejemplo de gender

Si quieres mostrar la siguiente frase en inglés.

The author is other

Y también quieres mostrar las siguientes frases según la propiedad gender del componente.

The author is female
The author is male

El siguiente ejemplo de código muestra cómo vincular la propiedad gender del componente y usar la cláusula select para expresar las tres situaciones anteriores en un elemento <span>.

La propiedad gender vincula las salidas a cada uno de los siguientes valores de cadena.

Valor Valor en inglés
female female
male male
other other

La cláusula select asigna los valores a las traducciones apropiadas. El siguiente ejemplo de código muestra la propiedad gender usada con la cláusula select.

src/app/app.component.html

<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">  Hello i18n!</h1><ng-container i18n>I don't output any element</ng-container><br /><img [src]="logo" i18n-title title="Angular logo" alt="Angular logo"/><br><button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button><span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span>({{ minutes }})<br><br><button type="button" (click)="male()">♂</button><button type="button" (click)="female()">♀</button><button type="button" (click)="other()">⚧</button><span i18n>The author is {gender, select, male {male} female {female} other {other}}</span><br><br><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><br><br><button type="button" (click)="toggleDisplay()">Toggle</button><div i18n [attr.aria-label]="toggleAriaLabel()">{{toggle()}}</div>

Ejemplo de gender y minutes

Combina diferentes cláusulas juntas, como las cláusulas plural y select. El siguiente ejemplo de código muestra cláusulas anidadas basadas en los ejemplos de gender y minutes.

src/app/app.component.html

<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">  Hello i18n!</h1><ng-container i18n>I don't output any element</ng-container><br /><img [src]="logo" i18n-title title="Angular logo" alt="Angular logo"/><br><button type="button" (click)="inc(1)">+</button> <button type="button" (click)="inc(-1)">-</button><span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{ minutes }} minutes ago}}</span>({{ minutes }})<br><br><button type="button" (click)="male()">♂</button><button type="button" (click)="female()">♀</button><button type="button" (click)="other()">⚧</button><span i18n>The author is {gender, select, male {male} female {female} other {other}}</span><br><br><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><br><br><button type="button" (click)="toggleDisplay()">Toggle</button><div i18n [attr.aria-label]="toggleAriaLabel()">{{toggle()}}</div>

Próximos pasos