---
title: "Creating custom Basic toolbar buttons"
description: "Creating custom Basic toolbar buttons for TinyMCE"
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/custom-basic-toolbar-button/"
md_url: "https://www.tiny.cloud/docs/tinymce/7/custom-basic-toolbar-button/index.md"
version: "7"
last_updated: "2024-10-09T05:34:31Z"
tokens: 1510
---
Important This page documents TinyMCE 7. For new projects, Tiny recommends using the latest, most up-to-date version. [See TinyMCE 8 documentation](../../latest/custom-basic-toolbar-button/).
# Creating custom Basic toolbar buttons

A basic button 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). |
| tooltip | string | optional | Text for button tooltip. |
| enabled | boolean | optional | default: `true` - Represents the button’s state. When `false`, the button is unclickable. Toggled by the button’s API. |
| onSetup | `(api) => (api) => void` | optional | default: `() => () => {}` - Function invoked when the button is rendered. For details, see: [Using `onSetup`](#using-onsetup). |
| onAction | `(api) => void` | required | Function invoked when the button is clicked. |
| NOTE: This feature is only available for TinyMCE 7.0 and later. | NOTE: This feature is only available for TinyMCE 7.0 and later. | NOTE: This feature is only available for TinyMCE 7.0 and later. | NOTE: This feature is only available for TinyMCE 7.0 and later. |
| shortcut | string | optional | Shortcut to display in the tooltip. To register a shortcut, see: [Add custom shortcuts to TinyMCE](../shortcuts/). |
| NOTE: This feature is only available for TinyMCE 7.4 and later. | NOTE: This feature is only available for TinyMCE 7.4 and later. | NOTE: This feature is only available for TinyMCE 7.4 and later. | NOTE: This feature is only available for TinyMCE 7.4 and later. |
| context | string | optional | default: `mode:design` - The context property dynamically enables or disables the button based on the editor’s current state. For details, see: [Context](../context/). |

## API

| Name | Value | Description |
| --- | --- | --- |
| isEnabled | `() => boolean` | Checks if the button is enabled. |
| setEnabled | `(state: boolean) => void` | Sets the button’s enabled state. |
| NOTE: This feature is only available for TinyMCE 6.4 and later. | NOTE: This feature is only available for TinyMCE 6.4 and later. | NOTE: This feature is only available for TinyMCE 6.4 and later. |
| setText | `(text: string) => void` | Sets the text label to display. |
| setIcon | `(icon: string) => void` | Sets the icon of the button. |

## Basic button example and explanation

The following example adds two buttons to the toolbar:

**Example**

```js
tinymce.init({
  selector: 'textarea#custom-toolbar-button',
  toolbar: 'customInsertButton customDateButton',
  setup: (editor) => {

    editor.ui.registry.addButton('customInsertButton', {
      text: 'My Button',
      onAction: (_) => editor.insertContent(`&nbsp;<strong>It's my button!</strong>&nbsp;`)
    });

    const toTimeHtml = (date) => `<time datetime="${date.toString()}">${date.toDateString()}</time>`;

    editor.ui.registry.addButton('customDateButton', {
      icon: 'insert-time',
      tooltip: 'Insert Current Date',
      enabled: false,
      onAction: (_) => editor.insertContent(toTimeHtml(new Date())),
      onSetup: (buttonApi) => {
        const editorEventCallback = (eventApi) => {
          buttonApi.setEnabled(eventApi.element.nodeName.toLowerCase() !== 'time');
        };
        editor.on('NodeChange', editorEventCallback);

        /* onSetup should always return the unbind handlers */
        return () => editor.off('NodeChange', editorEventCallback);
      }
    });
  },
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});
```
The first button inserts "It’s my button!" into the editor when clicked. The second button is an example of how `onSetup` works. This button inserts a `time` element containing the current date into the editor using a `toTimeHtml()` helper function - a simplified version of TinyMCE’s [insertdatetime](../insertdatetime/) plugin.

In this example an icon from the `insertdatetime` plugin is used to demonstrate how to use a registered icon. `disabled` is set to `true` so that the button is disabled when it is first rendered.

`onSetup` is used to listen to the editor’s [`NodeChange` event](../events/#editor-core-events) to disable the button when the cursor is inside a `time` element (or "node"). This ensures it is not possible to insert a `time` element into another `time` element.

## 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 () => {};`.
