---
title: "Custom Basic menu items"
description: "How to create custom basic menu items."
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/custom-basic-menu-items/"
md_url: "https://www.tiny.cloud/docs/tinymce/6/custom-basic-menu-items/index.md"
version: "6"
last_updated: "2022-11-30T01:26:11Z"
tokens: 866
---
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-basic-menu-items/).
# Custom Basic menu items

A basic menu item triggers its `onAction` function when clicked.

## Options

| 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. |
| enabled | boolean | optional | default: `true` - Represents the menu item’s state. When `false`, the menu item is unclickable. Toggled by the menu item’s API. |
| 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). |
| onAction | `(api) => void` | required | Function invoked when the menu item is clicked. |
| 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 basic menu item

```js
tinymce.init({
  selector: 'textarea',
  menu: {
    custom: { title: 'Custom Menu', items: 'undo redo basicitem' }
  },
  menubar: 'file edit custom',

  setup: (editor) => {
    editor.ui.registry.addMenuItem('basicitem', {
      text: 'My basic menu item',
      onAction: () => alert('Menu 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 () => {};`.
