How per-module translation files are merged into a single bundle per language, and how translations are added and validated.
The system ensures that translations from different modules are merged into a single bundle per language,
using the merge-i18n-plugin.js. After they are merged, all .json
files from src/assets/i18n directories are transferred to the webpack output directory. That includes
language-config.json, which contains the default language, the translation bundle version
and the available languages for the application. The configuration file is read, upon starting the application inside
ontotext-root-config.js#getLanguageConfig. The default language
is loaded and the app starts listening for ontotext-root-config.js#onLanguageChange
events. Once a language changes, the respective bundle is loaded and emitted via language-context.service.ts#updateLanguageBundle.
Modules listen for bundle changes from language-context.service.ts#onLanguageBundleChanged
and apply translation logic independently from each other.
Every module in the application must follow the convention of placing translation files under the src/assets/i18n directory.
For example:
packages/
module1/
src/assets/i18n/en.json
src/assets/i18n/fr.json
module2/
src/assets/i18n/en.json
src/assets/i18n/fr.json
Translation files should be JSON objects where the keys are the translation identifiers, and the values are the translated strings. For example:
src/assets/i18n/en.json:
{
"greeting": "Hello",
"farewell": {
"label": "Goodbye"
}
}
src/assets/i18n/fr.json:
{
"greeting": "Bonjour",
"farewell": {
"label": "Au revoir"
}
}
The merge-i18n-plugin.js aggregates these translation files across all modules and merges them into a single bundle for each language. For example:
packages/module1/src/assets/i18n/en.json and packages/module2/src/assets/i18n/en.json will be combined into a single en.json.
The output will look like this:
dist/${outputDirectory}/en.json
The plugin resolves conflicts by throwing 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:
Processing file: en.json
Error: Conflict detected for key 'menu.logo.link.title' in language 'en' in file: packages/workbench/src/assets/i18n/en.json
Automatic Directory Traversal: Scans all modules for src/assets/i18n folders.
Conflict Detection: Throws an error if there are duplicate keys in the same language.
JSON Merging: Combines all translations into one file per language.
Asset Emission: Writes the merged bundles to the specified output directory in the Webpack dist folder.
startDirectory: The base directory where the plugin begins searching for modules.
outputDirectory: The directory inside the Webpack output folder where the merged translation bundles will be written.
const { MergeI18nPlugin } = require('./plugins/MergeI18nPlugin');
module.exports = {
// Other Webpack configurations...
plugins: [
new MergeI18nPlugin({
startDirectory: 'packages',
outputDirectory: 'assets/i18n',
}),
],
};
availableLanguages array in language-config.json.src/assets/i18n folder, where there are translations.
The key in availableLanguages, should be the name of the new file translation, e.g. ${key}.json.
Avoid conflicting keys in your new bundle, as it will cause an error.${webpack.outputFolder}/${mergeI18nPlugin.outputDirectory}
(currently dist/assets/i18n) folder to verify that all translations are included and correctly merged.To validate translations locally:
npm run validate
If the project structure differs or the script is placed elsewhere, provide the project root manually:
SCRIPT_ROOT=/absolute/path/to/repo-root npm run validate
The script will generate a file:
translation-report.json
If issues are found, the script will exit with code 1.
On Jenkins, the script runs automatically in the Validate stage.
If issues are found:
Look for this file under “Build Artifacts”:
translation-report.json
See also: Developers Guide