From 08d3e10a420dca994918d904f4a05664d4651b3c Mon Sep 17 00:00:00 2001 From: Ben Szymanski Date: Tue, 7 Oct 2025 10:49:22 -0500 Subject: [PATCH 1/5] Update menus article --- .../extension-types/menu.md | 155 +++++++++++------- 1 file changed, 95 insertions(+), 60 deletions(-) diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md index e305a7b8155..24ef49f1884 100644 --- a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md +++ b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md @@ -1,25 +1,21 @@ -# Menu +--- +description: >- + Create menus that appear throughout the backoffice, in sidebars, button flyouts, and more. +--- -{% hint style="warning" %} -This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice. -{% endhint %} +# Menus + +Menu extensions contain one or more menu item extensions and can be placed throughout the backoffice - in sidebars, flyouts, and more. This article will cover how to create a menu with custom menu items.

Menu

## Creating a custom menu -In this section, you can learn how to register and create a custom Menu for the Umbraco backoffice. - -### Manifest - -The manifest file can be created using either JSON or TypeScript. Both methods are shown below. +Menu extensions can be created using either JSON or TypeScript. Both approaches are shown below. {% tabs %} - {% tab title="JSON" %} - -We can create the manifest using JSON in the `umbraco-package.json`. - +{% code title="umbraco-package.json" %} ```json { "type": "menu", @@ -27,18 +23,16 @@ We can create the manifest using JSON in the `umbraco-package.json`. "name": "My Menu" } ``` +{% endcode %} {% endtab %} - {% tab title="TypeScript" %} +Extension authors define the menu manifest, then register it dynamically/during runtime using a [Backoffice Entry Point](../../extending-overview/extension-types/backoffice-entry-point.md) extension. -The manifest can also be written in TypeScript. - -For this TypeScript example we used a [Backoffice Entry Point](../../extending-overview/extension-types/backoffice-entry-point.md) extension to register the manifests. - +{% code title="my-menu/manifests.ts" %} ```typescript import type { ManifestMenu } from '@umbraco-cms/backoffice/menu'; -const menuManifest: Array = [ +export const menuManifest: Array = [ { type: 'menu', alias: 'My.Menu', @@ -46,33 +40,43 @@ const menuManifest: Array = [ } ]; ``` +{% endcode %} -{% endtab %} +{% code title="entrypoints/entrypoints.ts" %} +```typescript +import type { + UmbEntryPointOnInit, +} from "@umbraco-cms/backoffice/extension-api"; +import { umbExtensionsRegistry } from "@umbraco-cms/backoffice/extension-registry"; +import { menuManifest } from "./../my-menu/manifests.ts"; +export const onInit: UmbEntryPointOnInit = (_host, _extensionRegistry) => { + console.log("Hello from my extension 🎉"); + + umbExtensionsRegistry.register(menuManifest); +}; +``` +{% endcode %} +{% endtab %} {% endtabs %} -# Menu Item +# Menu Items -

Menu Item

+Each menu consists of one or more menu item extensions. Extension authors can create customized menu items. -Menu items are the items that appear in the menu. +

Menu Item

-## Creating a custom menu items +## Creating menu items -In this section, you can learn how to add custom Menu Items to your Umbraco backoffice Menu. +Menu Item extensions can be created using either JSON or TypeScript. Both approaches are shown below. ### Manifest To add custom menu items, you can define a single MenuItem manifest and link an element to it. In this element, you can fetch the data and render as many menu items as you want based on that data. -The code snippets below show how to declare a new menu item using JSON or TypeScript. - {% tabs %} - {% tab title="JSON" %} - -We can create the manifest using JSON in the `umbraco-package.json`. - +{% code title="umbraco-package.json" %} ```json { "type": "menuItem", @@ -85,16 +89,18 @@ We can create the manifest using JSON in the `umbraco-package.json`. } } ``` - +{% hint style="info" %} +The `element` parameter is optional. Omitting it will render a menu item styled using Umbraco defaults. +{% endhint %} +{% endcode %} {% endtab %} - {% tab title="TypeScript" %} -The manifest can also be written in TypeScript. +Extension authors define the menu manifest, then register it dynamically/during runtime using a [Backoffice Entry Point](../../extending-overview/extension-types/backoffice-entry-point.md) extension. -For this TypeScript example we used a [Backoffice Entry Point](../../extending-overview/extension-types/backoffice-entry-point.md) extension to register the manifests. +The `element` attribute will point toward a custom Lit component, an example of which will be in the next section of this article. -{% code title="manifest.ts" overflow="wrap" lineNumbers="true" %} +{% code title="my-menu/manifests.ts" %} ```typescript const menuItemManifest: Array = [ { @@ -105,37 +111,51 @@ const menuItemManifest: Array = [ label: 'My Menu Item', menus: ["My.Menu"] }, - element: () => import('./menu-items.ts') } ]; ``` {% endcode %} +{% code title="entrypoints/entrypoints.ts" %} +```typescript +import type { + UmbEntryPointOnInit, +} from "@umbraco-cms/backoffice/extension-api"; +import { umbExtensionsRegistry } from "@umbraco-cms/backoffice/extension-registry"; +import { menuItemManifest } from "./../my-menu/manifests.ts"; -{% endtab %} +export const onInit: UmbEntryPointOnInit = (_host, _extensionRegistry) => { + console.log("Hello from my extension 🎉"); + umbExtensionsRegistry.register(menuItemManifest); +}; +``` +{% endcode %} +{% endtab %} {% endtabs %} -### The UI Element +### Custom menu items -#### Rendering menu items with Umbraco's UI menu item component +{% hint style="info" %} +**Note:** Displaying menu item extensions does not require extension authors to create custom menu item subclasss. This step is optional. +{% endhint %} -To render your menu items in Umbraco, you can use the [Umbraco UI Menu Item component](https://uui.umbraco.com/?path=/docs/uui-menu-item--docs). This component allows you to create nested menu structures with a few lines of code. +To render your menu items in Umbraco, extension authors can use the [Umbraco UI Menu Item component](https://uui.umbraco.com/?path=/docs/uui-menu-item--docs). This component enables nested menu structures with a few lines of markup. -By default, you can set the `has-children` attribute to display the caret icon indicating nested items. It will look like this: `?has-children=${bool}`. +`` nodes accept the `has-children` boolean attribute, which will display a caret icon indicating nested items. Tying this boolean attribute to a variable requires using the `?` Lit directive, which would look similar to this: `?has-children=${boolVariable}`. **Example:** -```tsx +```html ``` -#### Custom menu item element example +### Custom menu item element example -You can fetch the data and render the menu items using the Lit element above. By putting the result of the fetch in a `@state()`, we can trigger a re-render of the component when the data is fetched. +Custom elements can fetch the data and render menu items using markup, like above. Storing the results of the fetch in a `@state()` variable will trigger a re-render of the component when the value of the variable changes. {% code title="menu-items.ts" overflow="wrap" lineNumbers="true" %} ```typescript @@ -211,17 +231,14 @@ declare global { [elementName]: MyMenuItems; } } - ``` {% endcode %} - ## Tree Menu Item ### Manifest ```json -// it will be something like this { "type": "menuItem", "kind": "tree", @@ -242,22 +259,40 @@ The default element supports rendering a subtree of menu items. class UmbMenuItemTreeDefaultElement {} ``` -### Adding menu items to an existing menu +## Adding menu items to an existing menu -The backoffice comes with a couple of menus. +Extension authors are able to add their own additional menu items to the menus that ship with Umbraco. -* Content, Media, Settings, Templating, Dictionary, etc. +Some examples of these built-in menus include: -To add a menu item to an existing menu, you can use the `meta.menus` property. +* Content - `Umb.Menu.Content` +* Media - `Umb.Menu.Media` +* Settings - `Umb.Menu.StructureSettings` +* Templating - `Umb.Menu.Templating` +* ... -```typescript +Additional Umbraco menus (nine, total) can be found using the Extension Insights browser and selecting **Menu** from the dropdown. + +

Backoffice extension browser

+ +### Extending Menus + +To add a menu item to an existing menu, use the `meta.menus` property. + +{% code title="umbraco-package.json" %} +```json { - "type": "menuItem", - "alias": "My.MenuItem", - "name": "My Menu Item", - "meta": { - "label": "My Menu Item", - "menus": ["Umb.Menu.Content"] - } + "type": "menuItem", + "alias": "My.MenuItem", + "name": "My Menu Item", + "meta": { + "label": "My Menu Item", + "menus": ["Umb.Menu.Content"] + }, + "element": "menu-items.js" } ``` +{% endcode %} + +## See Also +* [Section Sidebar](sections/section-sidebar.md) for information on creating menus for navigation within section extensions. From 43d56b0ee3f3cd1709ed413dcd4640075ed2e5b9 Mon Sep 17 00:00:00 2001 From: Ben Szymanski Date: Sun, 12 Oct 2025 13:49:13 -0500 Subject: [PATCH 2/5] Revamp "Menus" documentation: updated examples to align with new JSON schema and TypeScript imports. Removed outdated code and restructured sections for clarity and consistency. --- .../extension-types/menu.md | 210 +++++------------- 1 file changed, 56 insertions(+), 154 deletions(-) diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md index 24ef49f1884..bd0b885e68f 100644 --- a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md +++ b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md @@ -18,9 +18,16 @@ Menu extensions can be created using either JSON or TypeScript. Both approaches {% code title="umbraco-package.json" %} ```json { - "type": "menu", - "alias": "My.Menu", - "name": "My Menu" + "$schema": "../../umbraco-package-schema.json", + "name": "My Package", + "version": "0.1.0", + "extensions": [ + { + "type": "menu", + "alias": "My.Menu", + "name": "My Menu" + } + ] } ``` {% endcode %} @@ -32,13 +39,11 @@ Extension authors define the menu manifest, then register it dynamically/during ```typescript import type { ManifestMenu } from '@umbraco-cms/backoffice/menu'; -export const menuManifest: Array = [ - { - type: 'menu', - alias: 'My.Menu', - name: 'My Menu' - } -]; +export const menuManifest: ManifestMenu = { + type: 'menu', + alias: 'My.Menu', + name: 'My Menu' +}; ``` {% endcode %} @@ -79,14 +84,21 @@ To add custom menu items, you can define a single MenuItem manifest and link an {% code title="umbraco-package.json" %} ```json { - "type": "menuItem", - "alias": "My.MenuItem", - "name": "My Menu Item", - "element": "./menu-items.ts", - "meta": { - "label": "My Menu Item", - "menus": ["My.Menu"] - } + "$schema": "../../umbraco-package-schema.json", + "name": "My Package", + "version": "0.1.0", + "extensions": [ + { + "type": "menuItem", + "alias": "My.MenuItem", + "name": "My Menu Item", + "element": "./menu-items.ts", + "meta": { + "label": "My Menu Item", + "menus": ["My.Menu"] + } + } + ] } ``` {% hint style="info" %} @@ -102,17 +114,17 @@ The `element` attribute will point toward a custom Lit component, an example of {% code title="my-menu/manifests.ts" %} ```typescript -const menuItemManifest: Array = [ - { - type: 'menuItem', - alias: 'My.MenuItem', - name: 'My Menu Item', - meta: { - label: 'My Menu Item', - menus: ["My.Menu"] - }, - } -]; +import type { ManifestMenuItem } from '@umbraco-cms/backoffice/menu'; + +export const menuItemManifest: ManifestMenuItem = { + type: 'menuItem', + alias: 'My.MenuItem', + name: 'My Menu Item', + meta: { + label: 'My Menu Item', + menus: ["My.Menu"] + }, +}; ``` {% endcode %} @@ -134,123 +146,6 @@ export const onInit: UmbEntryPointOnInit = (_host, _extensionRegistry) => { {% endtab %} {% endtabs %} -### Custom menu items - -{% hint style="info" %} -**Note:** Displaying menu item extensions does not require extension authors to create custom menu item subclasss. This step is optional. -{% endhint %} - -To render your menu items in Umbraco, extension authors can use the [Umbraco UI Menu Item component](https://uui.umbraco.com/?path=/docs/uui-menu-item--docs). This component enables nested menu structures with a few lines of markup. - -`` nodes accept the `has-children` boolean attribute, which will display a caret icon indicating nested items. Tying this boolean attribute to a variable requires using the `?` Lit directive, which would look similar to this: `?has-children=${boolVariable}`. - -**Example:** - -```html - - - - -``` - -### Custom menu item element example - -Custom elements can fetch the data and render menu items using markup, like above. Storing the results of the fetch in a `@state()` variable will trigger a re-render of the component when the value of the variable changes. - -{% code title="menu-items.ts" overflow="wrap" lineNumbers="true" %} -```typescript -import type { UmbMenuItemElement } from '@umbraco-cms/backoffice/menu'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { html, TemplateResult, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import { MyMenuItemResponseModel, MyMenuResource } from '../../../api'; - -const elementName = 'my-menu-item'; - -@customElement(elementName) -class MyMenuItems extends UmbLitElement implements UmbMenuItemElement { - @state() - private _items: MyMenuItemResponseModel[] = []; // Store fetched items - - @state() - private _loading: boolean = true; // Track loading state - - @state() - private _error: string | null = null; // Track any errors - - override firstUpdated() { - this.fetchInitialItems(); // Start fetching on component load - } - - // Fetch initial items - async fetchInitialItems() { - try { - this._loading = true; - this._items = ((await MyMenuResource.getMenuApiV1()).items); // Fetch root-level items - } catch (e) { - this._error = 'Error fetching items'; - } finally { - this._loading = false; - } - } - - // Render items - renderItems(items: MyMenuItemResponseModel[]): TemplateResult { - return html` - ${items.map(element => html` - - ${element.type === 1 - ? html`` - : html``} - - ${element.hasChildren ? this.renderItems(element.children) : ''} - - `)} - `; - } - - // Main render function - override render() { - if (this._loading) { - return html``; - } - - if (this._error) { - return html` - `; - } - - // Render items if loading is done and no error occurred - return this.renderItems(this._items); - } -} - -export { MyMenuItems as element }; - -declare global { - interface HTMLElementTagNameMap { - [elementName]: MyMenuItems; - } -} -``` -{% endcode %} - -## Tree Menu Item - -### Manifest - -```json -{ - "type": "menuItem", - "kind": "tree", - "alias": "My.TreeMenuItem", - "name": "My Tree Menu Item", - "meta": { - "label": "My Tree Menu Item", - "menus": ["My.Menu"] - } -} -``` - #### Default Element The default element supports rendering a subtree of menu items. @@ -282,14 +177,21 @@ To add a menu item to an existing menu, use the `meta.menus` property. {% code title="umbraco-package.json" %} ```json { - "type": "menuItem", - "alias": "My.MenuItem", - "name": "My Menu Item", - "meta": { - "label": "My Menu Item", - "menus": ["Umb.Menu.Content"] - }, - "element": "menu-items.js" + "$schema": "../../umbraco-package-schema.json", + "name": "My Package", + "version": "0.1.0", + "extensions": [ + { + "type": "menuItem", + "alias": "My.MenuItem", + "name": "My Menu Item", + "meta": { + "label": "My Menu Item", + "menus": ["Umb.Menu.Content"] + }, + "element": "menu-items.js" + } + ] } ``` {% endcode %} From 79532ab9ae23c29ed46055120eab614623fda7ee Mon Sep 17 00:00:00 2001 From: Ben Szymanski Date: Mon, 13 Oct 2025 03:27:53 -0500 Subject: [PATCH 3/5] Streamline "Menus" documentation: simplified descriptions, cross-linked with "Menu Items" article, and removed redundant "Menu Items" section as that's been moved to it's own article. --- .../extension-types/menu.md | 136 +----------------- 1 file changed, 3 insertions(+), 133 deletions(-) diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md index bd0b885e68f..60a7ea68ae5 100644 --- a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md +++ b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md @@ -1,11 +1,11 @@ --- description: >- - Create menus that appear throughout the backoffice, in sidebars, button flyouts, and more. + Create menus that appear throughout the backoffice, including sidebars and button flyouts. --- # Menus -Menu extensions contain one or more menu item extensions and can be placed throughout the backoffice - in sidebars, flyouts, and more. This article will cover how to create a menu with custom menu items. +Menu extensions contain one or more [menu item extensions](menu-item.md) and can appear throughout the backoffice—such as in sidebars and flyouts.

Menu

@@ -65,136 +65,6 @@ export const onInit: UmbEntryPointOnInit = (_host, _extensionRegistry) => { {% endtab %} {% endtabs %} -# Menu Items - -Each menu consists of one or more menu item extensions. Extension authors can create customized menu items. - -

Menu Item

- -## Creating menu items - -Menu Item extensions can be created using either JSON or TypeScript. Both approaches are shown below. - -### Manifest - -To add custom menu items, you can define a single MenuItem manifest and link an element to it. In this element, you can fetch the data and render as many menu items as you want based on that data. - -{% tabs %} -{% tab title="JSON" %} -{% code title="umbraco-package.json" %} -```json -{ - "$schema": "../../umbraco-package-schema.json", - "name": "My Package", - "version": "0.1.0", - "extensions": [ - { - "type": "menuItem", - "alias": "My.MenuItem", - "name": "My Menu Item", - "element": "./menu-items.ts", - "meta": { - "label": "My Menu Item", - "menus": ["My.Menu"] - } - } - ] -} -``` -{% hint style="info" %} -The `element` parameter is optional. Omitting it will render a menu item styled using Umbraco defaults. -{% endhint %} -{% endcode %} -{% endtab %} -{% tab title="TypeScript" %} - -Extension authors define the menu manifest, then register it dynamically/during runtime using a [Backoffice Entry Point](../../extending-overview/extension-types/backoffice-entry-point.md) extension. - -The `element` attribute will point toward a custom Lit component, an example of which will be in the next section of this article. - -{% code title="my-menu/manifests.ts" %} -```typescript -import type { ManifestMenuItem } from '@umbraco-cms/backoffice/menu'; - -export const menuItemManifest: ManifestMenuItem = { - type: 'menuItem', - alias: 'My.MenuItem', - name: 'My Menu Item', - meta: { - label: 'My Menu Item', - menus: ["My.Menu"] - }, -}; -``` -{% endcode %} - -{% code title="entrypoints/entrypoints.ts" %} -```typescript -import type { - UmbEntryPointOnInit, -} from "@umbraco-cms/backoffice/extension-api"; -import { umbExtensionsRegistry } from "@umbraco-cms/backoffice/extension-registry"; -import { menuItemManifest } from "./../my-menu/manifests.ts"; - -export const onInit: UmbEntryPointOnInit = (_host, _extensionRegistry) => { - console.log("Hello from my extension 🎉"); - - umbExtensionsRegistry.register(menuItemManifest); -}; -``` -{% endcode %} -{% endtab %} -{% endtabs %} - -#### Default Element - -The default element supports rendering a subtree of menu items. - -```typescript -class UmbMenuItemTreeDefaultElement {} -``` - -## Adding menu items to an existing menu - -Extension authors are able to add their own additional menu items to the menus that ship with Umbraco. - -Some examples of these built-in menus include: - -* Content - `Umb.Menu.Content` -* Media - `Umb.Menu.Media` -* Settings - `Umb.Menu.StructureSettings` -* Templating - `Umb.Menu.Templating` -* ... - -Additional Umbraco menus (nine, total) can be found using the Extension Insights browser and selecting **Menu** from the dropdown. - -

Backoffice extension browser

- -### Extending Menus - -To add a menu item to an existing menu, use the `meta.menus` property. - -{% code title="umbraco-package.json" %} -```json -{ - "$schema": "../../umbraco-package-schema.json", - "name": "My Package", - "version": "0.1.0", - "extensions": [ - { - "type": "menuItem", - "alias": "My.MenuItem", - "name": "My Menu Item", - "meta": { - "label": "My Menu Item", - "menus": ["Umb.Menu.Content"] - }, - "element": "menu-items.js" - } - ] -} -``` -{% endcode %} - ## See Also * [Section Sidebar](sections/section-sidebar.md) for information on creating menus for navigation within section extensions. +* [Menu Item](menu-item.md) for information on creating menu items. From 906f1d27ceaf4a79ce55eb06c2d85b981e3caf1b Mon Sep 17 00:00:00 2001 From: Esha Noronha <82437098+eshanrnh@users.noreply.github.com> Date: Tue, 28 Oct 2025 10:10:27 +0100 Subject: [PATCH 4/5] Update 16/umbraco-cms/customizing/extending-overview/extension-types/menu.md --- .../customizing/extending-overview/extension-types/menu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md index 60a7ea68ae5..e626211a3cb 100644 --- a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md +++ b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md @@ -1,6 +1,6 @@ --- description: >- - Create menus that appear throughout the backoffice, including sidebars and button flyouts. + Create menus that appear throughout the backoffice, including in sidebars and button flyouts. --- # Menus From 353622132724eeec8e7cab4385fe543a3cdac12f Mon Sep 17 00:00:00 2001 From: Esha Noronha <82437098+eshanrnh@users.noreply.github.com> Date: Tue, 28 Oct 2025 10:10:35 +0100 Subject: [PATCH 5/5] Update 16/umbraco-cms/customizing/extending-overview/extension-types/menu.md --- .../customizing/extending-overview/extension-types/menu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md index e626211a3cb..2cb8413faf1 100644 --- a/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md +++ b/16/umbraco-cms/customizing/extending-overview/extension-types/menu.md @@ -5,7 +5,7 @@ description: >- # Menus -Menu extensions contain one or more [menu item extensions](menu-item.md) and can appear throughout the backoffice—such as in sidebars and flyouts. +Menu extensions contain one or more [menu item extensions](menu-item.md) and can appear throughout the backoffice, such as in sidebars and flyouts.

Menu