Skip to content

Adding a Language

By default, a yuuvis shell client project ships with German (de) and English (en). This guide walks through everything needed to add a third language — from registering it in the project configuration through translating all keys and verifying the result at runtime.

  • The Localization concept is understood, particularly how i18n:extract and i18n:collect work and what i18n-external/ contains.
  • The yuuvis Client CLI is installed globally (npm install -g @yuuvis/client-cli).
  • You are working inside a yuuvis client project created with yuv new.

The examples below use Spanish (es) with the label Español. Substitute your own locale code and label throughout.

Run the CLI command from the root of your client project:

Terminal window
yuv add language es --label Español

This single command makes three changes to your project:

FileWhat changes
package.jsonNew locale appended to --lang= in the i18n:extract script
src/assets/_yuuvis/config/main.jsonNew entry added to core.languages
i18n-external/es.jsonCreated with {} (only if the file did not already exist)

After the command runs, package.json looks like this:

package.json (excerpt)
{
"scripts": {
"i18n:extract": "node ./scripts/i18n-extract.js --lang=de,en,es"
}
}

And main.json now declares the new language:

src/assets/_yuuvis/config/main.json (excerpt)
{
"core": {
"languages": [
{ "iso": "de", "label": "Deutsch" },
{ "iso": "en", "label": "English", "fallback": true },
{ "iso": "es", "label": "Español" }
]
}
}

Run the extraction script to generate an es.json file inside every locally developed library and app:

Terminal window
npm run i18n:extract

The script scans all src/ folders listed in angular.json for translation keys used in templates and TypeScript files. For each project it finds, it writes a new src/assets/i18n/es.json alongside the existing de.json and en.json files. The new file contains all keys found in the source, but the values are empty strings — they need to be translated.

Example result for a local app:

projects/mycompany/myapp/src/assets/i18n/
├── de.json ← existing, fully translated
├── en.json ← existing, fully translated
└── es.json ← new, all values empty
projects/mycompany/myapp/src/assets/i18n/es.json (after extract)
{
"myapp.action.cancel": "",
"myapp.action.submit": "",
"myapp.welcome.message": ""
}

Step 3: Populate external translation keys

Section titled “Step 3: Populate external translation keys”

Run the collect script to populate i18n-external/es.json with all keys from the yuuvis shell libraries and published apps that are installed as npm dependencies:

Terminal window
npm run i18n:collect

The script scans all @yuuvis/* packages in node_modules/ for i18n/ folders, merges their translations per language, and writes the result to i18n-external/. It then uses i18n-external/en.json as the key reference: every key present in the English file but missing from another language file is added with an empty value "".

After this run, i18n-external/es.json contains the full set of keys from all external libraries, with empty values everywhere:

i18n-external/es.json (excerpt, after first collect)
{
"yuv.app.drive.action.copy-link": "",
"yuv.app.drive.action.copy-link.description": "",
"yuv.app.drive.create.file": "",
"yuv.app.drive.create.folder": "",
"yuv.framework.action.delete.label": "",
...
}

The script also produces the final runtime file src/assets/_yuuvis/i18n/es.json, which at this point combines all local and external keys — all with empty values.

This is the main manual effort. You need to fill in translation values in two places.

Open i18n-external/es.json and translate every empty value. This file covers all translations from the yuuvis shell libraries and any published apps added with yuv add app.

i18n-external/es.json (excerpt, translated)
{
"yuv.app.drive.action.copy-link": "Copiar enlace",
"yuv.app.drive.action.copy-link.description": "Copia el enlace al portapapeles.",
"yuv.app.drive.create.file": "Subir archivo",
"yuv.app.drive.create.folder": "Crear carpeta",
"yuv.framework.action.delete.label": "Eliminar",
...
}

For every locally developed app and library, open the generated es.json in projects/**/src/assets/i18n/ and translate the values:

projects/mycompany/myapp/src/assets/i18n/es.json (translated)
{
"myapp.action.cancel": "Cancelar",
"myapp.action.submit": "Enviar",
"myapp.welcome.message": "¡Bienvenido!"
}

The client application itself also has its own translation file at src/assets/i18n/. This file is generated by i18n:extract alongside the project files and must be translated in the same way:

src/assets/i18n/es.json (translated)
{
"client.title": "Mi cliente"
}

Once translations are in place, run i18n:collect again to produce the final merged runtime file that includes all the translated values:

Terminal window
npm run i18n:collect

This regenerates src/assets/_yuuvis/i18n/es.json with everything merged and sorted. This is the file the application loads when a user selects Spanish.

Start the development server and switch the UI language to Spanish:

Terminal window
npm start

In the client, open the user settings and switch the language to Español. Verify that the UI renders in Spanish throughout, including labels, buttons, error messages, and app-specific strings.

Things to check:

  • Navigation bar labels
  • Action button labels
  • Empty state and error messages
  • Strings in any locally developed apps

Commit all translation files — sources and the generated runtime file:

Terminal window
git add i18n-external/es.json
git add projects/**/src/assets/i18n/es.json
git add src/assets/i18n/es.json
git add src/assets/_yuuvis/i18n/es.json
git commit -m "feat: add Spanish (es) language support"
FileWhy commit it
i18n-external/es.jsonPersistent store for external library translations — without it, every developer and CI/CD run starts with empty values
projects/**/src/assets/i18n/es.jsonSource translations for locally developed apps
src/assets/i18n/es.jsonSource translations for the client application itself
src/assets/_yuuvis/i18n/es.jsonPre-built runtime file — committing it avoids regenerating it on every npm start and production build

Maintaining translations when libraries update

Section titled “Maintaining translations when libraries update”

When you update a @yuuvis/* package that introduces new translation keys, i18n:collect automatically adds the new keys to i18n-external/es.json with empty values. Your existing translations are never overwritten.

Workflow after a library update:

Terminal window
npm install # install the new package version
npm run i18n:collect # pick up new keys → empty values added to es.json
# Translate the new empty values in i18n-external/es.json
npm run i18n:collect # regenerate runtime file with completed translations
git add i18n-external/es.json src/assets/_yuuvis/i18n/es.json
git commit -m "chore: add Spanish translations for new keys in x.y.z"

The new language does not appear in the language selector

Check that the language entry was added to core.languages in src/assets/_yuuvis/config/main.json. Verify iso, label, and that no trailing comma or JSON syntax error was introduced.

All strings show the key instead of a translation

The runtime file src/assets/_yuuvis/i18n/es.json is missing or empty. Run npm run i18n:collect and confirm the file is written with translated values.

i18n:collect does not create es.json in i18n-external/

The file must exist before i18n:collect can populate it. yuv add language creates it automatically. If you skipped the CLI command, create it manually:

Terminal window
echo '{}' > i18n-external/es.json
npm run i18n:collect

The new es.json in a local app is missing some keys

Re-run npm run i18n:extract. If keys are still missing, check that they use the translate pipe, [translate] directive, or marker() function — only these are detected by the extractor. Keys constructed dynamically at runtime (e.g. string concatenation) are invisible to static extraction and must be added to the JSON files manually.

Regional locale codes (e.g. pt-br) are not picked up

The i18n:collect script matches only two-letter JSON file names (de.json, es.json). Files named pt-br.json are silently skipped. Use the two-letter base code (pt) instead, or extend the collect script’s regex to support hyphenated codes.