
Umbraco Property Editor Ui
- 301 installs
- 26 repo stars
- Updated August 1, 2026
- umbraco/umbraco-cms-backoffice-skills
Helps with ai & agent building tasks.
About
umbraco-property-editor-ui is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- umbraco-property-editor-ui
- AI & Agent Building
- AI-coding skill
Umbraco Property Editor Ui by the numbers
- 301 all-time installs (skills.sh)
- +13 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #2,289 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/umbraco/umbraco-cms-backoffice-skills --skill umbraco-property-editor-uiAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 301 |
|---|---|
| repo stars | ★ 26 |
| Last updated | August 1, 2026 |
| Repository | umbraco/umbraco-cms-backoffice-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Umbraco Property Editor UI
What is it?
A Property Editor UI is the visual component that users interact with in the Umbraco backoffice to input and manage content data. It's one half of a property editor - the UI (client-side TypeScript) pairs with a Schema (server-side C#) that defines data storage.
Documentation
Always fetch the latest docs before implementing:
- Main docs: https://docs.umbraco.com/umbraco-cms/customizing/property-editors
- Tutorial: https://docs.umbraco.com/umbraco-cms/tutorials/creating-a-property-editor
- Configuration: https://docs.umbraco.com/umbraco-cms/tutorials/creating-a-property-editor/adding-configuration-to-a-property-editor
- Foundation: https://docs.umbraco.com/umbraco-cms/customizing/foundation
- Extension Registry: https://docs.umbraco.com/umbraco-cms/customizing/extending-overview/extension-registry
Reference Example
The Umbraco source includes a working example:
Location: /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/property-editor/
This example demonstrates a complete property editor UI implementation with configuration. Study this for production patterns.
Related Foundation Skills
- Umbraco Element: When implementing the UI element with UmbElementMixin
- Reference skill:
umbraco-umbraco-element
- State Management: When implementing reactive value updates
- Reference skill:
umbraco-state-management
- Localization: When adding multi-language support to labels
- Reference skill:
umbraco-localization
Workflow
1. Fetch docs - Use WebFetch on the URLs above 2. Ask questions - What data type? What UI components needed? Configuration options? 3. Generate files - Create manifest + element based on latest docs 4. Explain - Show what was created and how to test
Minimal Examples
Manifest (umbraco-package.json)
WARNING: ThepropertyEditorSchemaAliasbelow usesUmbraco.Plain.String, a built-in schema.
If you use a custom alias likeMyPackage.CustomSchema, you MUST have a corresponding C#DataEditoron the server or you'll get a 404 error when creating a Data Type.
{
"name": "My Property Editor",
"extensions": [
{
"type": "propertyEditorUi",
"alias": "My.PropertyEditorUi.Custom",
"name": "My Custom Editor",
"element": "/App_Plugins/MyEditor/editor.js",
"elementName": "my-editor-ui",
"meta": {
"label": "My Custom Editor",
"icon": "icon-edit",
"group": "common",
"propertyEditorSchemaAlias": "Umbraco.Plain.String"
}
}
]
}Element Implementation (editor.ts)
import { LitElement, html, css, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/property-editor';
@customElement('my-editor-ui')
export default class MyEditorElement extends UmbElementMixin(LitElement) implements UmbPropertyEditorUiElement {
@property({ type: String })
public value = '';
#onChange(e: Event) {
const input = e.target as HTMLInputElement;
this.value = input.value;
this.dispatchEvent(new UmbChangeEvent());
}
render() {
return html`
<uui-input
.value=${this.value || ''}
@change=${this.#onChange}
></uui-input>
`;
}
static styles = css`
:host {
display: block;
}
`;
}
declare global {
interface HTMLElementTagNameMap {
'my-editor-ui': MyEditorElement;
}
}With Configuration
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
@customElement('my-editor-ui')
export default class MyEditorElement extends UmbElementMixin(LitElement) implements UmbPropertyEditorUiElement {
@property({ type: String })
public value = '';
@state()
private _maxChars?: number;
@state()
private _placeholder?: string;
@property({ attribute: false })
public set config(config: UmbPropertyEditorConfigCollection) {
this._maxChars = config.getValueByAlias('maxChars');
this._placeholder = config.getValueByAlias('placeholder');
}
render() {
return html`
<uui-input
.value=${this.value || ''}
.placeholder=${this._placeholder || ''}
.maxlength=${this._maxChars}
@change=${this.#onChange}
></uui-input>
`;
}
}Configuration in Manifest
{
"type": "propertyEditorUi",
"alias": "My.PropertyEditorUi.Custom",
"name": "My Custom Editor",
"element": "/App_Plugins/MyEditor/editor.js",
"elementName": "my-editor-ui",
"meta": {
"label": "My Custom Editor",
"propertyEditorSchemaAlias": "Umbraco.Plain.String",
"settings": {
"properties": [
{
"alias": "maxChars",
"label": "Maximum Characters",
"propertyEditorUiAlias": "Umb.PropertyEditorUi.Integer"
},
{
"alias": "placeholder",
"label": "Placeholder Text",
"propertyEditorUiAlias": "Umb.PropertyEditorUi.TextBox"
}
],
"defaultData": [
{ "alias": "maxChars", "value": 100 }
]
}
}
}Built-in Schema Aliases (Safe Defaults)
The propertyEditorSchemaAlias in your manifest must reference a schema that exists on the server:
| Part | Location | Language |
|---|---|---|
| Property Editor UI | Client | TypeScript |
| Property Editor Schema | Server | C# |
- Built-in schemas (listed below) are always available - use these for simple storage needs
- Custom schemas require a C#
DataEditorclass - only needed for custom validation/conversion
These built-in schemas are always available:
| Schema Alias | Stores | Use Case |
|---|---|---|
Umbraco.Plain.String | string | Simple text values |
Umbraco.Integer | int | Numbers, ratings, counts |
Umbraco.Decimal | decimal | Prices, percentages |
Umbraco.Plain.Json | object | Complex JSON data |
Umbraco.DateTime | DateTime | Dates and times |
Umbraco.TrueFalse | bool | Toggles, checkboxes |
Umbraco.TextBox | string | Textbox with validation |
Umbraco.TextArea | string | Multi-line text |
Troubleshooting
See TROUBLESHOOTING.md for common issues including:
- 404 errors when creating Data Types
- Values not persisting with
Umbraco.Plain.Json
See UUI-GOTCHAS.md for UUI component issues (combobox, input, etc.).
---
That's it! Always fetch fresh docs, keep examples minimal, generate complete working code.
Property Editor UI Troubleshooting
Common issues and solutions when building property editor UIs.
---
404 Error When Creating Data Type
Symptom: Data Type fails to save, browser DevTools shows 404 when fetching schema.
Cause: The propertyEditorSchemaAlias references a schema that doesn't exist on the server.
Solution: 1. Use a built-in schema (recommended) - Change to Umbraco.Plain.String, Umbraco.Integer, etc. 2. Create a C# DataEditor - If you need custom behavior, implement the schema server-side:
[DataEditor(
alias: "MyPackage.CustomSchema",
ValueType = ValueTypes.Integer)]
public class MyCustomPropertyEditor : DataEditor
{
public MyCustomPropertyEditor(IDataValueEditorFactory dataValueEditorFactory)
: base(dataValueEditorFactory)
{ }
}See skill: umbraco-property-editor-schema for full details on creating custom schemas.
---
Value Not Persisting with Umbraco.Plain.Json
Symptom:
- User selects/enters a value in the property editor
- Value appears correct in console logs
- After save or page reload, the field is empty
- No errors in the console
Cause: The Umbraco.Plain.Json schema stores JavaScript objects directly, not JSON strings.
Common mistake - treating the value as a JSON string:
// WRONG: Trying to work with JSON strings
@property({ type: String })
public value = "";
#parseValue(): MyObject | null {
return this.value ? JSON.parse(this.value) : null;
}
#onChange(event: Event) {
const obj = event.target.value;
this.value = JSON.stringify(obj); // Umbraco expects an object, not a string!
this.dispatchEvent(new UmbChangeEvent());
}When you do this:
- Umbraco passes an object to your component
- You try to
JSON.parse()an object (fails silently or returns wrong type) - You
JSON.stringify()and save a string - Umbraco may store it, but the round-trip breaks
Solution: Work with objects directly when using Umbraco.Plain.Json:
// CORRECT: Work with objects directly
@property({ type: Object })
public value: MyObject | null = null;
#onChange(event: CustomEvent & { target: MyInputElement }) {
this.value = event.target.value; // Pass object directly
this.dispatchEvent(new UmbChangeEvent());
}
override render() {
return html`
<my-input
.value=${this.value}
@change=${this.#onChange}>
</my-input>
`;
}Schema Value Type Reference
| Schema Alias | Value Type | @property() Type |
|---|---|---|
Umbraco.Plain.String | string | { type: String } |
Umbraco.Plain.Integer | number | { type: Number } |
Umbraco.Plain.Json | object | { type: Object } |
Umbraco.TextBox | string | { type: String } |
Debugging Tip
Add console logs to your value setter to see what Umbraco is actually passing:
set value(val: unknown) {
console.log('[my-editor] value setter:', typeof val, val);
this._value = val as MyObject;
}---
UUI Component Issues
See UUI-GOTCHAS.md for issues specific to Umbraco UI Library components (combobox, input, etc.).
UUI Component Gotchas
Common issues when working with Umbraco UI Library (UUI) components in property editors.
---
Selection Not Working with uui-combobox
Symptom:
- User searches for items in a combobox dropdown
- User clicks a search result to select it
- The dropdown closes but the selected item doesn't display
- No errors in the console
Cause: The uui-combobox component fires events in this order when a selection is made:
1. @search event fires when the dropdown closes (with empty search term) 2. @change event fires to handle the selection
If your @search handler clears the search results array when the search term is empty, the results are cleared before the @change event can look up the selected item.
// PROBLEMATIC: Clearing results in search handler
#onSearch(event: UUIComboboxEvent) {
const searchTerm = combobox.search?.trim() ?? "";
if (!searchTerm) {
this._searchResults = []; // This clears results BEFORE @change fires!
return;
}
// ...perform search
}Solution: Maintain a separate cache of fetched items that persists independently of displayed search results:
// Cache persists independently of displayed results
#itemCache = new Map<string, ItemDetails>();
async #performSearch(query: string): Promise<void> {
// ... fetch results ...
this._searchResults = results;
// Cache all fetched items for later lookup
for (const item of results) {
this.#itemCache.set(item.id.toString(), item);
}
}
#onSelect(event: UUIComboboxEvent) {
const selectedId = combobox.value as string;
// Look up from cache, NOT from _searchResults
const selectedItem = this.#itemCache.get(selectedId);
if (selectedItem) {
this.value = selectedItem;
this._searchResults = []; // Safe to clear now
this.dispatchEvent(new UmbChangeEvent());
}
}