> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lumen.bjanczak.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Custom Toolbar Buttons to Lumen Editor

> Define a custom module object, merge it with Lumen Editor's built-in modules, and add it to the toolbar config to render new command buttons.

Lumen Editor's toolbar is driven by an array of module objects — each one describing a command that can appear as a button. You can define your own modules with exactly the same shape as the built-ins and slot them into any position in the toolbar. This lets you add new formatting commands, trigger custom actions, or integrate third-party functionality without touching the editor's internals.

## Module object shape

Every toolbar button corresponds to a module object with five fields:

| Field   | Type                       | Description                                                                                                                   |
| ------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `name`  | `string`                   | Unique identifier for the command, used to reference it in the `toolbar` config.                                              |
| `group` | `string`                   | Logical grouping: `'inline'`, `'block'`, `'history'`, `'insert'`, or any custom string. Used for styling and separator logic. |
| `icon`  | `string`                   | HTML string rendered inside the toolbar button — can be an emoji, a Unicode character, or an inline SVG.                      |
| `label` | `string`                   | Tooltip text shown on hover. Also used as the accessible label for the button.                                                |
| `exec`  | `(editor: Editor) => void` | Function called when the button is clicked. Receives the editor instance.                                                     |

<Note>
  The `icon` field is rendered as raw HTML inside the button element, so you can pass a full `<svg>...</svg>` string for crisp, scalable icons at any size — not just emoji or text characters.
</Note>

## Writing a custom module

Define a module object that follows the shape above. The example below adds a highlight command that applies a yellow background to the selected text:

```js theme={null}
const highlight = {
  name: 'highlight',
  group: 'inline',
  icon: '★',
  label: 'highlight',
  exec: (editor) => document.execCommand('hiliteColor', false, 'yellow')
};
```

The `exec` function receives the live editor instance, so you can call any public editor method, read the current selection, or dispatch DOM commands just like the built-in modules do.

## Merging with built-in modules

Lumen Editor exports a `modules` object whose values are all the built-in module definitions. Spread them alongside your custom module so the editor retains its default commands:

```js theme={null}
import { Editor, modules } from 'lumen-editor';

const highlight = {
  name: 'highlight',
  group: 'inline',
  icon: '★',
  label: 'highlight',
  exec: (editor) => document.execCommand('hiliteColor', false, 'yellow')
};

// Built-ins first, then your custom module(s)
const allModules = [...Object.values(modules), highlight];
```

This pattern preserves every built-in command while making `highlight` available for use in the toolbar config.

## Adding to the toolbar config

The `toolbar` option is an array of groups, where each group is an array of command `name` strings. Add your module's `name` to whichever group makes the most sense:

```js theme={null}
new Editor('#e', {
  modules: allModules,
  toolbar: [
    ['bold', 'italic', 'underline', 'highlight'],  // inline group
    ['bulletList', 'orderedList', 'blockquote'],    // block group
    ['undo', 'redo']                                // history group
  ]
});
```

Buttons are rendered in the order you list them within each group. Groups are separated by visual dividers in the toolbar.

## Full combined example

<CodeGroup>
  ```js ESM theme={null}
  import { Editor, modules } from 'lumen-editor';

  const highlight = {
    name: 'highlight',
    group: 'inline',
    icon: '★',
    label: 'highlight',
    exec: (editor) => document.execCommand('hiliteColor', false, 'yellow')
  };

  const editor = new Editor('#e', {
    modules: [...Object.values(modules), highlight],
    toolbar: [
      ['bold', 'italic', 'highlight'],
      ['bulletList', 'orderedList'],
      ['undo', 'redo']
    ]
  });
  ```

  ```html Script tag theme={null}
  <!-- Load lumen-editor from your preferred CDN or self-hosted bundle -->
  <script src="lumen-editor.umd.js"></script>
  <script>
    const { Editor, modules } = LumenEditor;

    const highlight = {
      name: 'highlight',
      group: 'inline',
      icon: '★',
      label: 'highlight',
      exec: (editor) => document.execCommand('hiliteColor', false, 'yellow')
    };

    const editor = new Editor('#e', {
      modules: [...Object.values(modules), highlight],
      toolbar: [
        ['bold', 'italic', 'highlight'],
        ['bulletList', 'orderedList'],
        ['undo', 'redo']
      ]
    });
  </script>
  ```
</CodeGroup>

<Tip>
  You can register multiple custom modules at once by appending them all to the spread: `[...Object.values(modules), highlight, strikeColor, clearFormat]`. As long as each module has a unique `name`, they can all coexist in the same editor instance.
</Tip>
