angular-localize
The angular-localize preset supports Angular's built-in i18n with @angular/localize.
Detection
The preset applies when the project depends on @angular/localize and angular.json has an i18n block. Libraries such as ng-bootstrap depend on @angular/localize without translating anything, so the dependency alone is not enough.
import { defineConfig } from '@x18n/core'
export default defineConfig({
presets: ['angular-localize'],
})Locale files
The preset reads the i18n block of every project in angular.json:
sourceLocale, as a string or as{ "code": "..." }, is the source locale. Angular's default isen-US.- Each entry of
localesis a translation file, as a path, a list of paths or{ "translation": ... }. - The source file is the one
ng extract-i18nwrites:messages.xlf,messages.xmb,messages.jsonormessages.arbin theoutputPathof theextract-i18ntarget, after itsformatandoutFileoptions.
{
"projects": {
"app": {
"i18n": {
"sourceLocale": "en-GB",
"locales": {
"tr": "src/locale/messages.tr.xlf"
}
},
"architect": {
"extract-i18n": {
"options": { "outputPath": "src/locale" }
}
}
}
}
}Every format of ng extract-i18n is supported:
| Format | Source file | Translation files |
|---|---|---|
XLIFF 1.2 (xlf, the default) | messages.xlf | messages.tr.xlf with <target> elements |
XLIFF 2.0 (xlf2) | messages.xlf | messages.tr.xlf with <target> elements |
XMB (xmb) | messages.xmb | messages.tr.xtb |
JSON (json) | messages.json | messages.tr.json |
ARB (arb) | messages.arb | messages.tr.arb |
An XLIFF file with a target language, or with a <target>, is a translation file: x18n reads and writes its targets. A new target keeps the placeholder markup of its <source>, so equiv-text, disp and type stay. JSON files hold their messages in translations, and the @@locale and @id entries of ARB files are metadata. Keys are flat: the id home.title is one key.
x18n does not create a translation file that is missing. As in Angular's guide, create it by copying the source file, then set the target language: target-language="tr" on <file> in XLIFF 1.2, trgLang="tr" on <xliff> in XLIFF 2.0, "locale": "tr" in JSON or "@@locale": "tr" in ARB.
Supported syntax
In templates, the i18n attribute and i18n-* attributes, with an optional meaning and description:
<h1 i18n="@@home.title">Hello</h1>
<p i18n="site intro|Shown on the home page">Welcome, {{ name }}!</p>
<a title="Blog" i18n-title>Blog</a>In TS and JS files, $localize tagged templates, and the inline template of a component:
const title = $localize`:@@title.projects:Projects`
const greeting = $localize`Hi ${name}:userName:!`A message with a custom id (@@home.title) uses it. A message without one gets the id Angular computes from its text and meaning, and x18n computes the same: the <p> above is 8889534073701065911. ICU expressions, nested elements, @if, @for and @switch blocks and custom placeholder names ({{ count // i18n(ph="count") }}) count. An ICU inside text is a message of its own, as Angular extracts it.
A generated id changes with the text, so renaming such a key in x18n does not change the template. Custom ids are easier to manage.
Placeholders
Angular placeholders: {$INTERPOLATION}, {$START_LINK}, {$CLOSE_LINK}. XLIFF and XMB placeholders read the same way.