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 manual file that no CLI tool updates:
libs/i18n/src/lib/models/fd-language.ts — the FdLanguage interface.
Every other file is auto-generated:
fd-language-key-identifier.ts— generated bytransform-translationstranslations_*.ts— generated bytransform-translationstranslations_*.properties— managed byi18n-manageCLI
If you skip 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: {
// ... existing keys ...
/** ARIA label for the calendar legend */
calendarLegendLabel: FdLanguageKey;
}
For keys with parameters:
/** Message showing count of selected items */
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 key to all 37
.propertiesfiles with the English default value - Generates the comment header (
#XACT: ARIA label for the calendar legend) - Runs
transform-translationswhich regeneratesfd-language-key-identifier.tsand alltranslations_*.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:
// BAD — ESLint member-ordering violation
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 .properties files. 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:transform-translations --skip-nx-cache
File Reference
| File | Manual/Generated | Purpose |
|---|---|---|
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_*.properties |
Managed by CLI | Source translation strings (37 locales) |
libs/i18n/src/lib/translations/translations_*.ts |
Generated | TypeScript translation modules |