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.
Prerequisites
Section titled “Prerequisites”- The Localization concept is understood, particularly how
i18n:extractandi18n:collectwork and whati18n-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.
Step 1: Register the new language
Section titled “Step 1: Register the new language”Run the CLI command from the root of your client project:
yuv add language es --label EspañolThis single command makes three changes to your project:
| File | What changes |
|---|---|
package.json | New locale appended to --lang= in the i18n:extract script |
src/assets/_yuuvis/config/main.json | New entry added to core.languages |
i18n-external/es.json | Created with {} (only if the file did not already exist) |
After the command runs, package.json looks like this:
{ "scripts": { "i18n:extract": "node ./scripts/i18n-extract.js --lang=de,en,es" }}And main.json now declares the new language:
{ "core": { "languages": [ { "iso": "de", "label": "Deutsch" }, { "iso": "en", "label": "English", "fallback": true }, { "iso": "es", "label": "Español" } ] }}Step 2: Extract local translation keys
Section titled “Step 2: Extract local translation keys”Run the extraction script to generate an es.json file inside every locally developed library
and app:
npm run i18n:extractThe 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{ "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:
npm run i18n:collectThe 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:
{ "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.
Step 4: Translate the content
Section titled “Step 4: Translate the content”This is the main manual effort. You need to fill in translation values in two places.
External library translations
Section titled “External library translations”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.
{ "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", ...}Local app and client translations
Section titled “Local app and client translations”For every locally developed app and library, open the generated es.json in
projects/**/src/assets/i18n/ and translate the values:
{ "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:
{ "client.title": "Mi cliente"}Step 5: Regenerate the final runtime file
Section titled “Step 5: Regenerate the final runtime file”Once translations are in place, run i18n:collect again to produce the final merged runtime
file that includes all the translated values:
npm run i18n:collectThis regenerates src/assets/_yuuvis/i18n/es.json with everything merged and sorted. This
is the file the application loads when a user selects Spanish.
Step 6: Test in the browser
Section titled “Step 6: Test in the browser”Start the development server and switch the UI language to Spanish:
npm startIn 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
Step 7: Commit to version control
Section titled “Step 7: Commit to version control”Commit all translation files — sources and the generated runtime file:
git add i18n-external/es.jsongit add projects/**/src/assets/i18n/es.jsongit add src/assets/i18n/es.jsongit add src/assets/_yuuvis/i18n/es.jsongit commit -m "feat: add Spanish (es) language support"| File | Why commit it |
|---|---|
i18n-external/es.json | Persistent store for external library translations — without it, every developer and CI/CD run starts with empty values |
projects/**/src/assets/i18n/es.json | Source translations for locally developed apps |
src/assets/i18n/es.json | Source translations for the client application itself |
src/assets/_yuuvis/i18n/es.json | Pre-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:
npm install # install the new package versionnpm run i18n:collect # pick up new keys → empty values added to es.json# Translate the new empty values in i18n-external/es.jsonnpm run i18n:collect # regenerate runtime file with completed translationsgit add i18n-external/es.json src/assets/_yuuvis/i18n/es.jsongit commit -m "chore: add Spanish translations for new keys in x.y.z"Troubleshooting
Section titled “Troubleshooting”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:
echo '{}' > i18n-external/es.jsonnpm run i18n:collectThe 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.