| name | general-add-localization |
| description | Add localization keys and use them in elements or controllers. Use when adding user-facing text that should be translatable โ labels, descriptions, error messages, button text, status text, or any string shown in the backoffice UI. |
| allowed-tools | Read, Write, Edit, Grep, Glob |
Add Localization
Add translatable text to the Umbraco backoffice.
What you need from the user
- The text to localize โ What the user sees (e.g., "Create item", "Status")
- Which group it belongs to โ Feature area (e.g.,
actions, general, content, user)
- Where it's used โ Element template, controller logic, or standalone component
Step 1: Add the key to the English dictionary
File: src/assets/lang/en.ts
This file exports a UmbLocalizationDictionary โ a nested object where top-level keys are groups and nested keys are the terms.
export default {
myFeature: {
myLabel: 'My Label',
myDescription: 'A description of the feature',
createFor: (name: string) => (name ? `Create item for ${name}` : 'Create'),
},
} satisfies UmbLocalizationDictionary;
Key naming rules
- Group: camelCase feature name (e.g.,
actions, general, content, media, user)
- Term: camelCase descriptive name (e.g.,
assignDomain, auditTrail, browse)
- Full key used in code:
group_termName (underscore separator)
Choosing a group
A group covers a shared UX area, not just the one component you're editing. Don't pick a group unilaterally โ confirm it with the user:
- If you already have a good idea of the scope (from the surrounding code, the feature being worked on, etc.), propose it: "This looks like it belongs to the
{scope} scope โ should that be the localization group?"
- If you don't, ask directly: "What is the common group name for this localization?"
- Either way, check for an existing match first. Search the groups already in
src/assets/lang/en.ts for one that already covers this UX area, and if you find one, ask whether it should be reused instead of creating a new group: "{existingGroup} already covers this โ should I use that instead?"
Examples already in this codebase:
blockEditor โ Block List, Block Grid, and Block RTE share the same block-configuration UX
contentTypeEditor โ Document Type, Media Type, and Member Type share the same editing UX
codeEditor โ anything embedding the code editor
Only create a new group once the user confirms no existing one fits.
Choosing a term
A term names the situation, not the wording โ two situations with identical English text today should still get separate terms, since the copy can diverge later.
Build it from two parts:
- Subject:
CreateBlock, ConfirmDelete, AddGroup.
- Presentation role:
Title, Description, Action, Label, Notice, Message, ValidationMessage, Headline, etc.
Combined (subject + role suffix): createAction, confirmDeleteTitle, addGroupDescription.
Example โ three terms for one dialog in the blockEditor group, same subject (confirmDeleteBlockGroup) with different roles:
confirmDeleteBlockGroupTitle: 'Delete group?',
confirmDeleteBlockGroupMessage: 'Are you sure you want to delete group <strong>%0%</strong>?',
confirmDeleteBlockGroupNotice: 'The content of these Blocks will still be present, editing of this content will no longer be available and will be shown as unsupported content.',
Grouping by subject keeps every piece of the dialog together, even though the wording shares nothing.
Value types
| Type | Use when | Example |
|---|
string | Static text | myLabel: 'My Label' |
(args) => string | Text with dynamic values | createFor: (name: string) => \Create ${name}`` |
Step 2: Use the localized text
In element templates โ this.localize.term()
Available on any class extending UmbLitElement. The localize property is provided automatically.
import { customElement, html } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
@customElement('umb-my-element')
export class UmbMyElement extends UmbLitElement {
override render() {
return html`<uui-button label=${this.localize.term('myFeature_myLabel')}></uui-button>`;
}
}
In templates โ <umb-localize> element
For inline localized text in HTML templates:
<umb-localize key="myFeature_myLabel"></umb-localize>
<umb-localize key="myFeature_myLabel">Fallback text</umb-localize>
In controllers or non-element classes โ UmbLocalizationController
import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api';
export class UmbMyManager extends UmbControllerBase {
readonly #localization = new UmbLocalizationController(this);
someMethod() {
const label = this.#localization.term('myFeature_myLabel');
}
}
Checklist