Translations
This page explains how the OpenAEV front-end is translated, how to add or change a translation, and which checks the CI runs.
How translation works
The front-end translation files live in openaev-front/src/utils/lang/:
| File | Language |
|---|---|
en.json |
English, the reference file |
de.json, es.json, fr.json, it.json |
German, Spanish, French, Italian |
ja.json, ko.json, ru.json, zh.json |
Japanese, Korean, Russian, Chinese |
A translation key is the English text itself: the component calls t('Add tags'), and every file maps "Add tags" to its translation. All nine files have the same keys.
Messages sent by the backend
For 400 and 409 responses, the front-end displays the backend error through t(error.message). The Java message must therefore match a key of en.json exactly, punctuation included. A message built by concatenation ("Unknown scenario: " + id) cannot be translated.
How to add or change a translation
- Wrap the text in
t():t('Add tags'), ort('{count} injects', { count })with a placeholder. -
Add the key to
en.json:The script only detects
t('…')calls with a single-quoted text and no other argument, in.js,.jsxand.tsxfiles. Add the other keys toen.jsonby hand:Not detected Example A call with options or placeholder values t('{count} injects', { count })A double-quoted text, or an escaped quote t("Add tags"),t('It\'s done')A call in a .tsfileasset-categories.ts,sampleData.tsA text passed as a prop or an object property that a component translates later title="Import a scenario",label: 'Seen'yarn i18n-checker(step 5) finds the first three cases. -
Translate the new keys into the eight other languages with DeepL:
You can also set
SUBSCRIPTION_KEYin the run configuration of your IDE. Only missing keys are sent to DeepL: existing translations are never overwritten. -
Review the diff. DeepL can mistranslate a word out of context, translate a field name or add quotes. Fix these by hand (see Translation rules).
-
Check the files:
Scripts
All scripts run from openaev-front/.
| Script | What it does |
|---|---|
yarn extract-translation |
Adds to en.json the missing keys of the simple t('…') calls (see How to add or change a translation). |
yarn auto-translation:all |
Translates with DeepL the keys missing from each language file, adjusts the case of the first letter to the source, then sorts the files. |
yarn sort-translation |
Sorts the keys of every language file. |
yarn i18n-checker |
Runs every check listed in Checks run by the CI. |
Checks run by the CI
The Frontend Quality & Unit Tests job runs yarn i18n-checker. The job fails on any of these checks.
| Check | Fails when |
|---|---|
| Missing key | A t('…') call uses a key absent from a language file, placeholders and escaped quotes included. |
| Catalog parity | A key of en.json is absent from another language file. This also covers the keys that reach t() through a variable (labels sent by the backend), which the missing-key check cannot see. |
| Untranslated value | A value is identical to the English one, unless it only holds protected terms or is listed in i18n-loanwords.json. |
| Placeholders | A translation does not keep the same {x}, {{ x }}, ${x} and tags, attributes included (<a href='${url}'>, </a>), as the English value, or contains a literal undefined. |
| Protected terms | A term of i18n-glossary.json present in the English value is missing from the translation. |
Configuration files
The files live in openaev-front/scripts/.
| File | Content |
|---|---|
i18n-glossary.json |
globalTerms: brand names, acronyms and standards that are never translated (OpenAEV, MITRE, Kubernetes, PowerShell…). |
i18n-loanwords.json |
Values that are legitimately identical to English: all for every language, then one list per language ("de": ["Dashboard"]). |
Translation rules
| Rule | Example |
|---|---|
| The case of the first letter follows the English source, in every language, German included. | breached → compromis, not Compromis |
| Protected terms stay as they are. | Kubernetes 클러스터, not 쿠버네티스 클러스터 |
| Field names, enum values and code identifiers are not translated. | Au moins un élément parmi exercise ou scenario… |
| No quotes are added when the source has none. | action_execution_arch ist erforderlich, not „action_execution_arch“ ist erforderlich |
| Placeholders and tags are kept unchanged. | {count} injects, <a href='${url}'>${url}</a> |
When a value is legitimately identical to English (a loanword such as Dashboard in German, or a technical name), add it to i18n-loanwords.json under its language instead of changing the translation.
Using IntelliJ plugins
-
i18n Ally manages the regex, checks missing translations and extracts keys.

-
Easy i18n adds, edits, deletes, sorts and checks translations.

What's next?
- Building and running from source -- Set up the front-end to run the translation scripts
- Platform -- Understand the architecture of the platform