How per-module translation files are merged into a single bundle per language, and how translations are added and validated.
src/i18n/locale-xx.json, outside the merge.src/assets/i18n JSON files.startDirectory, outputDirectory, replaceVersion.npm run validate locally.Validate stage and its artifact.Translations from different packages are merged into a single bundle per language by
merge-i18n-plugin.js, which writes them to dist/assets/i18n/. That includes
language-config.json, which contains the default
language, the translation bundle version and the available languages.
At startup, language-bootstrap.ts loads
the language configuration, selects the stored language (or the default one), and loads the default bundle into
LanguageContextService
(updateDefaultBundle, updateLanguageBundle). It then listens to onSelectedLanguageChanged; when the language
changes, it loads that bundle and emits it through updateLanguageBundle.
Packages listen for bundle changes with LanguageContextService#onLanguageBundleChanged and apply translations
independently. The Angular workbench feeds them to Transloco (see
frontend-angular).
packages/legacy-workbench keeps its own translations in src/i18n/locale-en.json / locale-fr.json, with the
language list in src/i18n/languages.json. They are not merged by the plugin; the legacy app loads them through
angular-translate (i18n/locale-<lang>.json). The validator still checks them together
with the other packages.
Every other package places its translation files under src/assets/i18n:
packages/
root-config/
src/assets/i18n/en.json
src/assets/i18n/fr.json
workbench/
src/assets/i18n/en.json
src/assets/i18n/fr.json
Translation files are JSON objects where the keys are the translation identifiers and the values are the translated strings:
src/assets/i18n/en.json:
{
"greeting": "Hello",
"farewell": {
"label": "Goodbye"
}
}
The merge plugin aggregates these files across all packages and merges them into a single bundle for each language.
For example, packages/root-config/src/assets/i18n/en.json and packages/workbench/src/assets/i18n/en.json are
combined into one dist/assets/i18n/en.json.
The plugin throws an error if multiple files define the same key for the same language.
For example:
module1/src/assets/i18n/en.json
{
"some-prop": "Hello",
"menu.logo.link.title": {
"label": "Goodbye"
}
}
module2/src/assets/i18n/en.json:
{
"another-prop": "Bonjour",
"menu.logo.link.title": {
"another-label": "Different Goodbye"
}
}
Will result in an error, similar to this one:
Error: Conflict detected for key 'menu.logo.link.title' in file: packages/workbench/src/assets/i18n/en.json
src/assets/i18n folder.dist folder.startDirectory: the base directory where the plugin begins searching for packages.outputDirectory: the directory inside the webpack output folder where the merged bundles are written.replaceVersion: a transform applied to the content (replaces the [AIV]{version}[/AIV] placeholder).From webpack.config.common.js:
const {MergeI18nPlugin} = require('./webpack/merge-i18n-plugin.js');
new MergeI18nPlugin({
startDirectory: './packages',
outputDirectory: 'assets/i18n',
replaceVersion
});
availableLanguages array in language-config.json.src/assets/i18n folder that has translations. The key in
availableLanguages is the file name: ${key}.json. Avoid conflicting keys.src/i18n/locale-${key}.json and the language to src/i18n/languages.json.dist/assets/i18n to verify that all translations are included.To validate translations locally:
npm run validate
This runs the validate script of packages/root-config and of packages/legacy-workbench. The root-config script
reads the translations of every package, legacy locale-xx.json files included, and reports missing and untranslated
keys, placeholder or HTML-tag differences between languages, and keys defined in more than one package.
If the project structure differs, provide the project root manually:
SCRIPT_ROOT=/absolute/path/to/repo-root npm run validate
The root-config script writes a translation-report.json file and exits with code 1 if issues are found.
On Jenkins, the script runs automatically in the Validate stage.
If issues are found:
Look for translation-report.json under “Build Artifacts”.
See also: Developers Guide