---
title: "Custom Nested menu items"
description: "How to create custom Nested menu items."
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/custom-nested-menu-items/"
md_url: "https://www.tiny.cloud/docs/tinymce/6/custom-nested-menu-items/index.md"
version: "6"
last_updated: "2022-11-30T01:26:11Z"
tokens: 925
---
Important This page documents TinyMCE 6. For new projects, Tiny recommends using the latest, most up-to-date version. [See TinyMCE 8 documentation](../../latest/custom-nested-menu-items/).
# Custom Nested menu items

A nested menu item is a menu item with a submenu. Registering a submenu this way allows it to be reused in menubar menus and toolbar button menus without having to define the submenu twice. The submenu can contain any combination of basic menu items and toggle menu items.

| Name | Value | Requirement | Description |
| --- | --- | --- | --- |
| text | string | optional | Text to display if no icon is found. |
| icon | string | optional | Name of the icon to be displayed. Must correspond to an icon: in the [icon pack](../editor-icon-identifiers/), in a [custom icon pack](../creating-an-icon-pack/), or added using the [`addIcon` API](../apis/tinymce.editor.ui.registry/#addIcon). |
| value | string | optional | A value to associate with the menu item. |
| onSetup | `(api) => (api) => void` | optional | default: `() => () => {}` - Function invoked when the menu item is rendered, each time its menu is opened. For details, see: [Using `onSetup`](#using-onsetup). |
| getSubmenuItems | `() => string` or `MenuItem[]` | required | Function invoked when the menu item is clicked to open its submenu. Must return either a space separated string of registered menu names or an array of basic, toggle or nested menu items specifications. |
| shortcut | string | optional | Text to display in the shortcut label. To register a shortcut, see: [Add custom shortcuts to TinyMCE](../shortcuts/). |

## API

| Name | Value | Description |
| --- | --- | --- |
| isEnabled | `() => boolean` | Checks if the menu item is enabled. |
| setEnabled | `(state: boolean) => void` | Sets the menu item’s enabled state. |

## Example: creating a nested menu item

```js
tinymce.init({
  selector: 'textarea',
  menu: {
    custom: { title: 'Custom Menu', items: 'undo redo nesteditem' }
  },
  menubar: 'file edit custom',
  setup: (editor) => {
    editor.ui.registry.addNestedMenuItem('nesteditem', {
      text: 'My nested menu item',
      getSubmenuItems: () => [{
        type: 'menuitem',
        text: 'My submenu item',
        onAction: () => alert('Submenu item clicked')
      }]
    });
  }
});
```

## Using `onSetup`

`onSetup` is a complex property. It takes a function that is passed the component’s API and should return a callback that is passed the component’s API and returns nothing. This occurs because `onSetup` runs whenever the component is rendered, and the returned callback is executed when the component is destroyed. This is essentially an `onTeardown` handler, and can be used to unbind events and callbacks.

To clarify, in code `onSetup` may look like this:

```js
onSetup: (api) => {
  // Do something here on component render, like set component properties or bind an event listener

  return (api) => {
    // Do something here on teardown, like unbind an event listener
  };
};
```
To bind a callback function to an editor event use `editor.on(eventName, callback)`. To unbind an event listener use `editor.off(eventName, callback)`. Any event listeners *should* be unbound in the teardown callback. The only editor event which does not need to be unbound is `init` e.g. `editor.on('init', callback)`.

> **Note:**
> - The callback function for `editor.off()` should be the same function passed to `editor.on()`. For example, if a `editorEventCallback` function is bound to the `NodeChange` event when the button is created, `onSetup` should return `(api) => editor.off('NodeChange', editorEventCallback)`.
> - If `onSetup` does not have any event listeners or only listens to the `init` event, `onSetup` can return an empty function e.g. `return () => {};`.
