Skip to content

Guide: Adding translations

GeronimoLeLanToussaintJalaUniversity edited this page Jun 16, 2026 · 1 revision

Guide: Adding translations to a new page

Context

This project uses Angular i18n with English as the source language and Spanish as a translation. The build generates two versions of the app: /en/ and /es/.


Step 1 — Mark text in the HTML

For text in native HTML elements, add the i18n attribute:

<!-- Simple text -->
<h1 i18n="Description of the text">Upload Content</h1>

<!-- Native attributes (aria-label, placeholder, alt) -->
<button i18n-aria-label="Description" aria-label="Go back">...</button>
<input i18n-placeholder="Description" placeholder="E.g.: Week 3" />

⚠️ i18n-* only works on native HTML elements, not on Angular components (app-button, app-stat-card, etc.).


Step 2 — Mark text in TypeScript

For strings used as component inputs or inside data arrays, use $localize:

// In the component class
readonly submitLabel = $localize`:Submit button label:Submit`;

// In data arrays (like in login-page.ts)
readonly items = [
  { title: $localize`:Item title:My Title` }
];

Then bind it normally in the HTML:

<app-button [ariaLabel]="submitLabel">...</app-button>

Step 3 — Extract the strings

From the QuizzArenaUI folder (where package.json is):

npx ng extract-i18n --output-path src/locale

This updates src/locale/messages.xlf with the new strings and their auto-generated IDs.


Step 4 — Add the Spanish translation

Open src/locale/messages.es.xlf and for each new string that appeared in messages.xlf, add an entry with <target>:

<!-- In messages.xlf (auto-generated, do NOT edit) -->
<trans-unit id="1234567890" datatype="html">
  <source>Upload Content</source>
  <note priority="1" from="description">Upload content page title</note>
</trans-unit>

<!-- In messages.es.xlf (this one you edit) -->
<trans-unit id="1234567890" datatype="html">
  <source>Upload Content</source>
  <target>Cargar Contenido</target>
  <note priority="1" from="description">Upload content page title</note>
</trans-unit>

The id must match exactly with the one in messages.xlf.

For text with interpolation ({{ variable }}):

<trans-unit id="..." datatype="html">
  <source> Welcome, <x id="INTERPOLATION" equiv-text="{{ name }}"/> </source>
  <target> Bienvenido, <x id="INTERPOLATION" equiv-text="{{ name }}"/> </target>
</trans-unit>

Step 5 — Verify

npm run build:i18n

If the output shows No translation found for "...", a entry is missing in messages.es.xlf. You can find the ID and source text in messages.xlf.

Once the build finishes with no translation warnings, serve the app:

serve .\dist\QuizzArenaUI\browser\

Navigate to http://localhost:3000/ → redirects to /en/ in English. From the language selector you can switch to /es/.


Key rules

✅ Do ❌ Don't
Only edit messages.es.xlf Edit messages.xlf manually
Write text in English in HTML/TS Write text in Spanish in HTML/TS
Use i18n-aria-label on native elements Use i18n-aria-label on Angular components
Run extract-i18n after adding new strings Copy IDs from memory