Customize buttons

Redactor splits editing actions across several UI areas — the main toolbar, floating bars, and dropdown menus. You can change which buttons appear in each area through init options or through the API when building plugins.

For the full option reference, see Buttons settings and Dropdown settings.

UI areas#

Area Option Default buttons Opens
Toolbar buttons.toolbar add, source, format, bold, italic, … —
Extrabar buttons.extrabar hotkeys —
Context buttons.context format, bold, italic, link, … —
Control buttons.control toggle control dropdown
Addbar dropdown.addbar text, heading, image, … block insert menu (+)
Control dropdown dropdown.control add, format, move-up, trash, … ⋮ on a block
Format dropdown.format text, h1–h4, quote, lists, … “Turn into” menu
Inline dropdown.inline code, underline, sup, sub, … “More formatting” menu
List dropdown.list / dropdown.haslist bullet, numbered, todo, indent list type menu

Static bars (toolbar, extrabar, context, control) share the same button list mechanics. Dropdown menus use dropdown.* arrays plus optional *Items objects.

Two ways to customize#

1. Replace the list (array)

Pass a new array to set order and which built-in buttons appear. Omitted names are not shown.

const app = Redactor('#entry', {
    buttons: {
        toolbar: ['add', 'bold', 'italic', 'link', 'image'],
        context: ['bold', 'italic', 'link'],
        extrabar: ['undo', 'redo']
    },
    dropdown: {
        format: ['text', 'h1', 'h2', 'h3', 'quote'],
        addbar: ['text', 'heading', 'image', 'quote', 'table'],
        inline: ['code', 'underline', 'highlight', 'removeinline'],
        control: ['add', 'format', 'trash'],
        list: ['bulletlist', 'numberedlist'],
        haslist: ['bulletlist', 'numberedlist', 'indent', 'outdent']
    }
});

dropdown.haslist is used when the caret is inside a list; dropdown.list is used outside lists.

2. Extend or hide (add / hide)

Keep the default list and add custom buttons or hide built-in ones.

const app = Redactor('#entry', {
    toolbar: {
        add: {
            save: {
                title: 'Save',
                command: 'output.save',
                position: { after: 'image' }
            }
        },
        hide: ['table', 'source']
    },
    extrabar: {
        hide: ['hotkeys']
    },
    context: {
        hide: ['moreinline']
    },
    addbar: {
        hide: ['layout', 'wrapper'],
        add: {
            banner: {
                title: 'Banner',
                command: 'block.insert',
                params: { type: 'wrapper', template: '<div class="banner"></div>' }
            }
        }
    },
    control: {
        hideDropdown: ['duplicate'],
        addDropdown: {
            blockColor: {
                title: 'Color',
                command: 'blockColor.open'
            }
        }
    }
});
Bar Add keys Hide keys
Toolbar toolbar.add toolbar.hide
Extrabar extrabar.add extrabar.hide
Context context.add context.hide
Control bar control.add control.hide
Control dropdown control.addDropdown control.hideDropdown
Addbar addbar.add or addbarItems addbar.hide

Dropdown format and inline use formatItems and inlineItems at init (same shape as add):

const app = Redactor('#entry', {
    formatItems: {
        lead: { title: 'Lead paragraph', command: 'format.set', params: { type: 'text', classname: 'lead' } }
    },
    inlineItems: {
        kbd: true  // enable built-in kbd entry from buttonsObj
    }
});

Toolbar#

Main row above the editor.

buttons: {
    toolbar: ['add', 'format', 'bold', 'italic', 'link', 'image']
}

Extra buttons and hidden names:

toolbar: {
    add: { templates: { title: 'Templates', command: 'templates.open' } },
    hide: ['table']
}

Disable the toolbar entirely: toolbar: false.

Extrabar#

Right side of the toolbar row (undo/redo, hotkeys, plugin actions).

buttons: {
    extrabar: ['undo', 'redo', 'hotkeys']
}

Disable: extrabar: false.

Context bar#

Floating toolbar on text selection.

buttons: {
    context: ['bold', 'italic', 'highlight', 'link']
}

Disable: context: false. See Context settings for click, exclude, include.

Control bar#

Floating handle on the focused block. buttons.control lists visible buttons; toggle opens the control dropdown.

buttons: {
    control: ['toggle', 'add', 'format']
},
dropdown: {
    control: ['add', 'format', 'move-up', 'move-down', 'duplicate', 'trash']
}

Disable the control bar: control: false.

Addbar dropdown#

Opened by the + button. Block types in dropdown.addbar; custom entries via addbarItems or addbar.add:

dropdown: {
    addbar: ['text', 'heading', 'image', 'quote', 'table']
},
addbarItems: {
    callout: {
        title: 'Callout',
        command: 'block.insert',
        params: { type: 'wrapper', template: '<aside class="callout"></aside>' }
    }
}

Also available but not in the default list: address, dlist.

Format dropdown#

“Turn into” menu (format button). Built-in entries map to block types (text, h1, h2, …).

dropdown: {
    format: ['text', 'h1', 'h2', 'h3', 'quote', 'bulletlist', 'numberedlist']
}

Inline dropdown#

“More formatting” menu (moreinline button).

dropdown: {
    inline: ['code', 'underline', 'sup', 'sub', 'highlight', 'kbd', 'removeinline']
}

List dropdown#

Opened by the list toolbar button. Set changes automatically when the caret is inside a list.

dropdown: {
    list: ['bulletlist', 'numberedlist', 'todo'],
    haslist: ['bulletlist', 'numberedlist', 'todo', 'indent', 'outdent']
}

Custom icons#

Override SVG icons for any built-in button name:

buttons: {
    icons: {
        bold: '<svg width="24" height="24" viewBox="0 0 24 24">…</svg>',
        italic: '<svg width="24" height="24" viewBox="0 0 24 24">…</svg>'
    }
}

Keys match button names (bold, add, trash, …). Per-button icon in add / plugin config still overrides a single button.

Button config#

Each button is an object (stored in buttonsObj for built-ins):

Field Description
title Label or tooltip (## lang.key ## for i18n)
icon SVG string
command Command to run, e.g. 'inline.set', 'block.insert'
params Arguments passed to the command
position Placement — see below
observer 'module.method' — hide or replace button at runtime
for Show only for certain block types ('editable', ['image'], …)

Position

position: 'first'           // start of the bar
position: 'last'            // end of the bar
position: 3                 // numeric index
position: { after: 'bold' } // after another button
position: { before: 'link' }

Add or remove buttons in plugins#

In a plugin start() method, register the button definition and attach it to the bars you need.

Register a new button

registerButton adds or merges into buttonsObj (title, icon, command):

start() {
    const button = this.app.registerButton('greeting', {
        title: '## greeting.title ##',
        icon: '<svg …>',
        command: 'greeting.insert'
    });

    this.app.toolbar.add('greeting', {
        ...button,
        position: { after: 'add' }
    });
}

Add to a bar

Module Method Use for
app.toolbar .add(name, config) Main toolbar
app.extrabar .add(name, config) Extrabar
app.context .add(name, config) Context bar
app.control .add(name, config) Control bar
app.control .addDropdown(name, config) Control ⋮ menu
app.addbar .add(name, config) Add (+) menu
app.format .add(name, config) Format dropdown
app.inline .add(name, config) Inline dropdown

addDynamic on toolbar/extrabar inserts a button into the DOM after the bar is built (useful for late-loaded plugins).

Remove buttons

this.app.toolbar.remove('table', 'image');
this.app.context.remove('moreinline');
this.app.addbar.remove('layout');
this.app.format.remove('h5');
this.app.inline.remove('highlight');
this.app.control.removeDropdown('duplicate');

Removed names stay hidden until the editor is reconfigured.

Example: button in several places

start() {
    const button = this.app.registerButton('snippets', {
        title: 'Snippets',
        icon: this.options.icon,
        command: 'snippets.open'
    });

    this.app.addbar.add('snippets', button);
    this.app.toolbar.add('snippets', { ...button, position: { after: 'add' } });
    this.app.context.add('snippets', button);
}

Commands from outside#

Same API via app.invoke:

app.invoke('toolbar.add', 'custom', { title: 'Run', command: 'myPlugin.run' });
app.invoke('toolbar.remove', 'table');