Functions for loading and managing translations at runtime, enabling dynamic language switching and translation loading without requiring build-time compilation.
Loads translations for use by $localize when doing runtime translation.
/**
* Load translations for use by $localize at runtime.
* Loading new translations overwrites previous ones with same MessageId.
* Messages are only processed once when first encountered.
*
* @param translations - Map from message ID to translated message string
*/
function loadTranslations(translations: Record<MessageId, TargetMessage>): void;
type MessageId = string;
type TargetMessage = string;Usage Examples:
import { loadTranslations } from "@angular/localize";
// Load Spanish translations
loadTranslations({
"4286451273117902052": "¡Hola, Mundo!",
"2788806693285683417": "¡Hola, {$PH}!",
"1234567890123456789": "Hay {$itemCount} elementos para {$userName}."
});
// Load from external source
async function loadSpanishTranslations() {
const response = await fetch('/translations/es.json');
const translations = await response.json();
loadTranslations(translations);
}
// Overwrite existing translation
loadTranslations({
"4286451273117902052": "¡Saludos, Mundo!" // Overwrites previous
});Removes all translations that were loaded using loadTranslations().
/**
* Remove all translations for $localize.
* Clears all translations loaded into memory and resets translate function.
*/
function clearTranslations(): void;Usage Examples:
import { clearTranslations } from "@angular/localize";
// Clear all loaded translations
clearTranslations();
// Switch languages by clearing and reloading
function switchLanguage(locale: string) {
clearTranslations();
return loadTranslationsForLocale(locale);
}The internal translation function that processes messages using loaded translations.
/**
* Translate message parts and substitutions using loaded translations.
* Reorders substitutions as indicated in matching translation.
* Warns on missing translations and returns original on error.
*
* @param messageParts - Template string array parts
* @param substitutions - Substitution values
* @returns Tuple with translated parts and reordered substitutions
*/
function translate(
messageParts: TemplateStringsArray,
substitutions: readonly any[]
): [TemplateStringsArray, readonly any[]];Message IDs are computed hashes that uniquely identify translatable strings:
// Source: $localize`Hello, World!`
// Message ID: "4286451273117902052"
// Source: $localize`Hello, ${name}!`
// Message ID: "2788806693285683417"Translations use {$PLACEHOLDER_NAME} syntax for placeholders:
{
// Simple message
"4286451273117902052": "¡Hola, Mundo!",
// With placeholder
"2788806693285683417": "¡Hola, {$PH}!",
// With named placeholders
"1234567890123456789": "Hay {$itemCount} elementos para {$userName}.",
// HTML with placeholders (from Angular templates)
"5555555555555555555": "pre{$START_TAG_SPAN}inner-pre{$START_BOLD_TEXT}bold{$CLOSE_BOLD_TEXT}inner-post{$CLOSE_TAG_SPAN}post"
}Angular templates with i18n attributes generate $localize calls:
<!-- Template -->
<div i18n>pre<span>inner-pre<b>bold</b>inner-post</span>post</div>
<!-- Compiled to -->
ɵɵi18n(1, $localize`pre{$START_TAG_SPAN}inner-pre{$START_BOLD_TEXT}bold{$CLOSE_BOLD_TEXT}inner-post{$CLOSE_TAG_SPAN}post`);import { loadTranslations } from "@angular/localize";
import "@angular/localize/init";
// 1. Load translations for target locale
loadTranslations({
"4286451273117902052": "¡Hola, Mundo!",
"2788806693285683417": "¡Hola, {$PH}!"
});
// 2. Use $localize normally
const greeting = $localize`Hello, World!`;
console.log(greeting); // "¡Hola, Mundo!"
const personal = $localize`Hello, ${name}!`;
console.log(personal); // "¡Hola, Alice!"import { loadTranslations, clearTranslations } from "@angular/localize";
async function setLanguage(locale: string) {
// Clear existing translations
clearTranslations();
// Load new translations
const translations = await fetchTranslations(locale);
loadTranslations(translations);
// All subsequent $localize calls use new translations
}
async function fetchTranslations(locale: string) {
const response = await fetch(`/translations/${locale}.json`);
return response.json();
}
// Switch to Spanish
await setLanguage('es');
console.log($localize`Hello, World!`); // "¡Hola, Mundo!"
// Switch to French
await setLanguage('fr');
console.log($localize`Hello, World!`); // "Bonjour, le monde!"import { loadTranslations } from "@angular/localize";
// Missing translation handling
loadTranslations({
// Only some translations provided
"4286451273117902052": "¡Hola, Mundo!"
// "2788806693285683417" missing
});
// Missing translation logs warning and returns original
const missing = $localize`Hello, ${name}!`;
// Console: "No translation found for..."
// Returns: "Hello, Alice!"// Development: runtime translations for quick iteration
if (process.env.NODE_ENV === 'development') {
loadTranslations(require('./translations/es.json'));
}
// Production: compile-time replacement (no runtime cost)
// $localize calls replaced by build toolsclass TranslationService {
private loaded = new Set<string>();
async loadLanguage(locale: string) {
if (this.loaded.has(locale)) return;
const translations = await import(`./translations/${locale}.json`);
loadTranslations(translations.default);
this.loaded.add(locale);
}
}