name: i18n-manage
description: Add, rename, or remove i18n translation keys in fundamental-ngx (updates FdLanguage interface, .properties files, and generated types)
argument-hint: [add|rename|remove] key [value]
i18n Key Management: $ARGUMENTS
If $ARGUMENTS is empty, ask the user what operation they need (add, rename, or remove) and for which key.
Critical Context
The i18n system has one translation file that developers edit:
libs/i18n/src/lib/translations/translations.properties — the base English translation strings.
The CLI reads this file and generates all localized TypeScript files:
translations.ts — base English translations
translations_*.ts — localized translations (de, es, fr, etc.)
Additionally, the FdLanguage interface must be manually maintained:
libs/i18n/src/lib/models/fd-language.ts — the FdLanguage interface.
Translation teams edit: Language-specific .properties files (translations_de.properties, translations_es.properties, etc.)
The language-specific .properties files are read by the i18n-manage --command=sync script when generating TypeScript files. When translation teams update these files, running i18n-manage --command=sync will pick up those translations automatically.
Every other file is auto-generated:
fd-language-key-identifier.ts — generated by i18n-manage --command=sync
translations_*.properties - delivered by external translation team after translating changes to translations.properties
translations_*.ts — generated by i18n-manage operations from translations.properties and translations_*.properties
If you skip updating fd-language.ts, the build will fail with a misleading error (see Troubleshooting below). This is the single most common mistake when working with i18n keys.
Add a Key
Step 1: Update fd-language.ts (MANUAL — required)
Open libs/i18n/src/lib/models/fd-language.ts and add the property to the FdLanguage interface.
Find the correct section (e.g., coreCalendar, coreButton). If the section doesn't exist, create it.
coreCalendar: {
calendarLegendLabel: FdLanguageKey;
}
For keys with parameters:
itemsSelected: FdLanguageKey<{ count: number }>;
Step 2: Run the CLI (handles everything else)
nx run i18n:i18n-manage --command=add --key=coreCalendar.calendarLegendLabel --value="Calendar Legend" --commentType=XACT --comment="ARIA label for the calendar legend"
This single command:
- Adds the new key
calendarLegendLabel to translations.properties with the comment described in the arguments
- Adds this default English value for each locale's
ts file (e.g., translations.ts, translations_es.ts, translations_de.ts)
Comment types (auto-detected from key name if --commentType is omitted):
| Type | Usage | Auto-detected from |
|---|
| XACT | ARIA labels, screen reader text | key contains aria |
| XBUT | Button labels | key contains button |
| XFLD | Form input labels | key contains label |
| XTIT | Titles and headings | key contains title |
| XMSG | Messages, descriptions | default fallback |
| XTOL | Tooltips | — |
| XCKL | Checkbox text | — |
| XRBL | Radio button text | — |
| XSEL | Dropdown/select values | — |
| XLNK | Link text | — |
| YINS | User instructions | — |
| NOTR | No translation needed | — |
Step 3: Verify
nx run i18n:i18n-manage --command=validate
nx run i18n:build --skip-nx-cache
Rename a Key
Step 1: Update fd-language.ts (MANUAL)
Rename the property in the FdLanguage interface.
Step 2: Run the CLI
nx run i18n:i18n-manage --command=rename --key=coreButton.oldName --newKey=coreButton.newName
Step 3: Update component references
Search for usages of the old key string in component files:
grep -rn "coreButton.oldName" libs/core/ libs/platform/ --include="*.ts" --include="*.html"
Update all occurrences to the new key.
Step 4: Verify
nx run i18n:i18n-manage --command=validate
nx run i18n:build --skip-nx-cache
Remove a Key
Step 1: Verify the key is unused
grep -rn "theKey.toRemove" libs/core/ libs/platform/ libs/btp/ libs/cx/ --include="*.ts" --include="*.html"
Do NOT remove a key that is still referenced in components.
Step 2: Update fd-language.ts (MANUAL)
Remove the property from the FdLanguage interface. If it was the last key in a section, remove the entire section.
Step 3: Run the CLI
nx run i18n:i18n-manage --command=remove --key=theKey.toRemove
Step 4: Verify
nx run i18n:i18n-manage --command=validate
nx run i18n:build --skip-nx-cache
Using the Key in Components
In templates (pipe)
@Component({
imports: [FdTranslatePipe],
template: `<span>{{ ('coreCalendar.calendarLegendLabel' | fdTranslate)() }}</span>`
})
The pipe returns Signal<string> — the () invocation is required.
In TypeScript (single key)
protected readonly _label = resolveTranslationSignal('coreCalendar.calendarLegendLabel');
In TypeScript (multiple keys)
private readonly _translate = resolveTranslationSignalFn();
private readonly _label = this._translate('coreCalendar.closeCalendarLabel');
private readonly _description = this._translate('coreCalendar.calendarDayViewDescription');
In host bindings
Inline resolveTranslationSignalFn() to avoid ESLint member-ordering violations:
@Component({
host: { '[attr.aria-label]': '_ariaLabel()' }
})
export class CalendarLegendComponent {
protected readonly _ariaLabel = resolveTranslationSignalFn()('coreCalendar.calendarLegendLabel');
}
Do NOT split into two fields — protected must come before private per ESLint:
private readonly _resolve = resolveTranslationSignalFn();
protected readonly _ariaLabel = this._resolve('coreCalendar.calendarLegendLabel');
Troubleshooting
TS2554: Expected 2 arguments, but got 1
On a call like resolveTranslationSignalFn()('coreCalendar.calendarLegendLabel').
Cause: The key exists in fd-language-key-identifier.ts (auto-generated) but NOT in fd-language.ts (manual). You forgot Step 1.
Why: The type resolver walks ObjectPathType<FdLanguage, Key>. When the property is missing from the interface, it resolves to never, making FdLanguageKeyCtx<Key> non-undefined, which forces the type system to demand a second argument.
Fix: Add the missing property to fd-language.ts.
Key "x" already exists
The key is already in translations.properties. Use rename or update instead of add.
nx run i18n:i18n-manage --command=search --searchTerm=keyName
nx run i18n:i18n-manage --command=update --key=coreButton.save --value="New Value"
Generated files not updating
nx run i18n:i18n-manage --command=sync --skip-nx-cache
File Reference
| File | Manual/Generated | Purpose |
|---|
libs/i18n/src/lib/translations/translations.properties | Generated by i18n-manage --command=add | Base English translation strings (developer edits this) |
libs/i18n/src/lib/models/fd-language.ts | MANUAL | FdLanguage interface — runtime type shape |
libs/i18n/src/lib/models/fd-language-key-identifier.ts | Generated | Union type of all valid key strings |
libs/i18n/src/lib/translations/translations_*.ts | Generated | TypeScript translation modules (37 locales) — consumed by the application |
libs/i18n/src/lib/translations/translations_*.properties | Delivered from external translation team | Localized translation strings — read by scripts to generate translations_*.ts |