Creating custom menu items

Use Cases

  • Create a shortcut for an action or a series of actions that the user repeatedly does.

  • Create a button for custom behavior.

How to create custom menu items

The methods for adding custom menu items are in the UI Registry part of the editor API editor.ui.registry. The API has three methods for adding menu items:

  • editor.ui.registry.addMenuItem(identifier, configuration)

  • editor.ui.registry.addNestedMenuItem(identifier, configuration)

  • editor.ui.registry.addToggleMenuItem(identifier, configuration)

The two arguments these methods take are:

  • identifier - a unique name for the button

  • configuration - an object containing your configuration for that button.

Define the custom toolbar button with the setup callback of the TinyMCE configuration to add it to the editor. This callback is invoked automatically for every initialized editor instance. Access to the UI registry API occurs when the callback receives a reference to the editor instance as its argument.

Example of adding a custom menu item

tinymce.init({
  selector: '#editor',
  menu: {
    custom: { title: 'Custom Menu', items: 'undo redo myCustomMenuItem' }
  },
  menubar: 'file edit custom',
  setup: (editor) => {
    editor.ui.registry.addMenuItem('myCustomMenuItem', {
      text: 'My Custom Menu Item',
      onAction: () => alert('Menu item clicked')
    });
  }
});
The identifier used to create the menu item must be included in the menu option in the TinyMCE configuration for it to be added to the menubar’s menus. It will not be added to the menubar’s menus if menu is not configured correctly.

Interactive example

This example shows you how to add some simple menu items to a new "custom" menu.

  • TinyMCE

  • HTML

  • JS

  • Edit on CodePen

<textarea id="custom-menu-item">
  <p><img style="display: block; margin-left: auto; margin-right: auto;" title="Tiny Logo" src="https://www.tiny.cloud/docs/images/logos/android-chrome-256x256.png" alt="TinyMCE Logo" width="128" height="128"></p>
  <h2 style="text-align: center;">Welcome to the TinyMCE editor demo!</h2>
  <p>Select a menu item from the listbox above and it will insert contents into the editor at the caret position.</p>

  <h2>Got questions or need help?</h2>
  <ul>
    <li>Our <a href="https://www.tiny.cloud/docs/tinymce/6/">documentation</a> is a great resource for learning how to configure TinyMCE.</li>
    <li>Have a specific question? Try the <a href="https://stackoverflow.com/questions/tagged/tinymce" target="_blank" rel="noopener"><code>tinymce</code> tag at Stack Overflow</a>.</li>
    <li>We also offer enterprise grade support as part of <a href="https://www.tiny.cloud/pricing">TinyMCE premium plans</a>.</li>
  </ul>

  <h2>Found a bug?</h2>
  <p>If you think you have found a bug please create an issue on the <a href="https://github.com/tinymce/tinymce/issues">GitHub repo</a> to report it to the developers.</p>

  <h2>Finally ...</h2>
  <p>Thanks for supporting TinyMCE! We hope it helps you and your users create great content.<br/>
    All the best from the TinyMCE team.</p>
</textarea>
tinymce.init({
  selector: 'textarea#custom-menu-item',
  height: 500,
  toolbar: false,
  menubar: 'custom',
  menu: {
    custom: { title: 'Custom menu', items: 'basicitem nesteditem toggleitem' }
  },
  setup: (editor) => {
    let toggleState = false;

    editor.ui.registry.addMenuItem('basicitem', {
      text: 'My basic menu item',
      onAction: () => editor.insertContent(`<p>Here's some content inserted from a basic menu!</p>`)
    });

    editor.ui.registry.addNestedMenuItem('nesteditem', {
      text: 'My nested menu item',
      getSubmenuItems: () => [
        {
          type: 'menuitem',
          text: 'My submenu item',
          onAction: () => editor.insertContent(`<p>Here's some content inserted from a submenu item!</p>`)
        }
      ]
    });

    editor.ui.registry.addToggleMenuItem('toggleitem', {
      text: 'My toggle menu item',
      onAction: () => {
        toggleState = !toggleState;
        editor.insertContent(`<p class="toggle-item">Here's some content inserted from a toggle menu!</p>`);
      },
      onSetup: (api) => {
        api.setActive(toggleState);
        return () => {};
      }
    });
  },
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});