Skip to main content
Version: 11.14.0

i18n Translation Overrides

The idea in one sentence

The app loads translations from the library. The override system lets you replace specific words without touching the library files.


How it works (step by step)

Think of it like a sticker book:

  1. The library provides the base sticker sheet (original translations).
  2. You place your custom stickers on top (override files).
  3. Where you put a sticker, it hides what was underneath. Where you don't, the original shows through.

In code terms:

base translations + your overrides = final translations
{ label: "Bookmarks" } + { label: "Mes Bookmarks" } = { label: "Mes Bookmarks" }

File structure

src/assets/i18n/
├── bookmarks/
│ ├── en.json ← library base file (do NOT edit)
│ ├── fr.json
│ └── de.json
├── collections/
│ ├── en.json ← library base file (do NOT edit)
│ ├── fr.json
│ └── de.json
└── overrides/YOUR files go here
├── bookmarks/
│ ├── en.json
│ ├── fr.json
│ └── de.json
└── collections/
├── en.json
├── fr.json
└── de.json

Rule: mirror the same folder/file structure under overrides/.


How to override a translation

1. Find the key you want to change

Open the base file, e.g. src/assets/i18n/bookmarks/en.json:

{
"label": "Bookmarks",
"myBookmarks": "My Bookmarks",
"noBookmarks": "No bookmarks yet"
}

2. Create (or edit) the matching override file

Create src/assets/i18n/overrides/bookmarks/en.json and put only the keys you want to change:

{
"label": "My Saved Items"
}

You don't need to copy everything — only what you want to override.

3. The result at runtime

{
"label": "My Saved Items", ← from your override
"myBookmarks": "My Bookmarks", ← from the library (unchanged)
"noBookmarks": "No bookmarks yet" ← from the library (unchanged)
}

How to add a new scope to the override system

By default, the override system is disabled for all scopes.

To add a new scope (e.g. savedSearches):

1. Open src/config/transloco-loader-overrides.ts and add the scope name to the list:

const OVERRIDDEN_SCOPES = ["savedSearches"];

2. Create the override folder and files:

src/assets/i18n/overrides/savedSearches/en.json
src/assets/i18n/overrides/savedSearches/fr.json
src/assets/i18n/overrides/savedSearches/de.json

Even if they are empty ({}), the files must exist (an HTTP 404 is silently ignored, but it's cleaner to have them).


How the pieces fit together

FileRole
transloco-loader-overrides.tsCustom loader — fetches base + override, merges them
transcolo-providers.tsRegisters the loader in the Angular app
deepmerge.tsDeep-merges the two JSON objects (nested keys work too)
assets/i18n/<scope>/<lang>.jsonBase translations from the library
assets/i18n/overrides/<scope>/<lang>.jsonYour custom overrides

Nested keys work too

Your override files support deep nesting. For example:

Base:

{
"actions": {
"save": "Save",
"cancel": "Cancel"
}
}

Override:

{
"actions": {
"save": "Keep it"
}
}

Result:

{
"actions": {
"save": "Keep it", ← overridden
"cancel": "Cancel" ← kept from base
}
}

FAQ

Q: What if my override file is missing or returns a 404?
A: No problem. The loader catches the error and treats it as an empty override {}. The base translations load normally.

Q: Do I need to include all keys in my override file?
A: No — only the ones you want to change.

Q: What if the same key appears in both files?
A: The override always wins.