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');