Editor

Core editor instance returned by Redactor(...). All methods below are called on app in page code, or on this.app inside plugins.

stop#

Tears down a running editor: stops modules and plugins, clears state and services, removes the initialized class from the host element. Emits app:stop.

app.stop();

destroy#

Fully removes the editor instance: calls stop() when loaded, unregisters from Redactor.instances, emits app:destroy. Use when the editor is no longer needed in the page.

app.destroy();

setContent#

Replaces the entire document with new content. Clears the current selection before parsing.

Parameters:

  • content (string | object) — HTML string, or JSON document when format is 'json'
  • options.format ('html' | 'json', default 'html') — how to interpret content
  • options.caret (false | 'start' | 'end', default false) — move caret after insert

Returns: boolean — always true when the call completes

app.setContent('<h1>Title</h1><p>Text</p>');

app.setContent(jsonDoc, { format: 'json', caret: 'start' });

setJson#

Shortcut for setContent with JSON format.

Parameters:

  • content (array | { blocks: array }) — block list, or an object with a blocks array
  • caret (false | 'start' | 'end', default false) — caret position after load

Returns: boolean — result of setContent

app.setJson([
    { type: 'heading', data: { level: 1, content: 'Title' } },
    { type: 'text', data: { content: 'Body.' } }
]);

// Equivalent wrapper form:
app.setJson({
    blocks: [
        { type: 'text', data: { content: 'Body.' } }
    ]
});

clearContent#

Empties the editable area and unregisters all blocks. Does not insert a default paragraph.

Returns: boolean — true when complete

app.clearContent();

setEmpty#

Clears the document and inserts one default text block with caret at the start. Emits editor:empty.

Returns: boolean — true when complete

app.setEmpty();

insertHtml#

Inserts HTML at the current caret, selection, or configured insert position.

Parameters:

  • html (string) — HTML to insert
  • options.caret ('start' | 'end' | 'before' | 'after', default 'end') — caret placement after insert
  • options.position ('top' | 'bottom') — insert relative to first/last block instead of selection
  • options.target (HTMLElement) — insert next to a specific element
  • options.targetPosition ('before' | 'after') — side of target element
  • options.notifyChanges (boolean, default true) — emit blocks:change after insert

Returns: { nodes, blocks } — inserted DOM nodes and mounted block instances (same as inserter)

app.insertHtml('<p>Inserted paragraph</p>');

app.insertHtml('<figure>…</figure>', { position: 'bottom' });

insertBlock#

Inserts a block instance at the current insert context.

Parameters:

  • block (Block) — mounted or prepared block instance
  • options (object) — same insert options as insertHtml

Returns: { nodes, blocks } — insert result from the inserter

const block = app.blocks.create('image', { src: '/photo.jpg' });
app.insertBlock(block, { caret: 'end' });

getEditor#

Returns the root editable element.

Returns: HTMLElement | null — editable root, or null before host is ready

const editable = app.getEditor();

getHtml#

Returns serialized document HTML (cleaned for output).

Returns: string — HTML string

const html = app.getHtml();

getText#

Returns plain text from the editable, without invisible characters.

Returns: string — text content

const text = app.getText();

getJson#

Returns the document as a JSON tree.

Returns: object — JSON document

const json = app.getJson();

getContent#

Generic content export with format and output options.

Parameters:

  • format ('html' | 'json' | 'nodes' | 'blocks', default 'html') — output shape
  • options (object) — passed to the output module (e.g. tidy for HTML)

Returns: string | object | Array — depends on format

const html = app.getContent('html', { tidy: true });
const blocks = app.getContent('blocks');

getNodes#

Returns document content as an array of DOM nodes built from JSON.

Returns: Node[] — root-level nodes

const nodes = app.getNodes();

getBlocks#

Returns document content as an array of block instances.

Returns: Block[] — mounted blocks

const blocks = app.getBlocks();

getRawHtml#

Returns the editable innerHTML as-is, without output cleaning.

Returns: string — raw HTML from the editable element

const raw = app.getRawHtml();

getEmail#

Returns email HTML when the email plugin is active; otherwise falls back to getContent().

Parameters:

  • tidy (boolean, default true) — run output tidying

Returns: string — HTML string

const emailHtml = app.getEmail();

getEmailText#

Returns plain-text email body when the email plugin is active; otherwise getText().

Parameters:

  • tidy (boolean, default true) — normalize whitespace

Returns: string — plain text

const plain = app.getEmailText();

setEditorDisabled#

Enables or disables editing. Updates UI lock state, syncs a host <textarea> when present, and emits editor:disabled / editor:enabled.

Parameters:

  • disabled (boolean) — true to disable interaction
  • options.syncTextarea (boolean, default true) — mirror state on the host textarea element
app.setEditorDisabled(true);
app.setEditorDisabled(false, { syncTextarea: false });

setEditorReadonly#

Sets read-only mode. Content is visible but not editable. Emits editor:readonly / editor:readwrite.

Parameters:

  • readonly (boolean) — true for read-only
  • options.syncTextarea (boolean, default true) — mirror readOnly on host textarea
app.setEditorReadonly(true);

isEditorDisabled#

Returns: boolean — true when the editor is disabled

if (app.isEditorDisabled()) return;

isEditorReadonly#

Returns: boolean — true when the editor is read-only

if (app.isEditorReadonly()) showViewBanner();

isEditorInteractionLocked#

Returns: boolean — true when disabled or read-only

if (app.isEditorInteractionLocked()) return;

isEditorEmpty#

Checks whether the editable HTML is effectively empty (no meaningful text or blocks).

Returns: boolean — true when empty

if (!app.isEditorEmpty()) {
  app.setEmpty();
}

isMode#

Checks the current host mode.

Parameters:

  • name (string) — mode id, e.g. 'iframe'

Returns: boolean — true when hostMode matches

if (app.isMode('iframe')) {
  // iframe-specific logic
}

hasFocus#

Returns: boolean — true when caret, selection, or block focus is inside the editable

if (app.hasFocus()) saveDraft();

isBlur#

Returns: boolean — true when the editor does not have focus

if (app.isBlur()) hideFloatingToolbar();

focusEditor#

Moves focus to the first or last block in the document.

Parameters:

  • options.position ('start' | 'end', default 'start') — which end of the document to focus

Returns: Block | null — focused block, or null when there are no blocks

app.focusEditor({ position: 'end' });

blurEditor#

Removes native focus from the editable (or a focused child inside it), clears selection and block selection chrome, closes the dropdown, applies blur styling, and emits editor:blur.

Parameters:

  • options.reason (string, default 'program') — reason passed to the editor:blur event

Returns: boolean — true when complete

app.blurEditor({ reason: 'modal-open' });

blurOtherEditors#

Calls blurEditor on every instance in Redactor.instances except the current one. Useful when several editors share a page (for example with toolbar.sharedTarget) and focus moves to this editor.

Parameters:

  • options.reason (string, default 'program') — reason passed to each editor:blur event

Returns: boolean — true when complete

app.blurOtherEditors({ reason: 'focus-switch' });

isAllSelected#

Returns: boolean — true when the entire document is selected

if (app.isAllSelected()) {
  app.insertHtml('<p>Replaced all</p>');
}

saveSelection#

Stores the current caret position as a character offset for later restore.

app.saveSelection();
// … modify DOM …
app.restoreSelection();

restoreSelection#

Restores caret from the last saveSelection() call. Clears the stored offset after restore.

app.saveSelection();
app.setContent('<p>New</p>');
app.restoreSelection(); // only works if offset is still valid

on#

Subscribes to an editor event. Accepts a single name or an array of names. Handlers registered via init events option are bound with this = app.

Parameters:

  • event (string | string[]) — event name (editor:ready or legacy editor.ready)
  • handler (function) — callback; receives payload object (and stop on hook events)
app.on('editor:ready', () => {
  console.log('Ready');
});

app.on(['blocks:change', 'editor:change'], () => syncPreview());

onFirst#

Same as on, but the handler is prepended and runs before other listeners.

Parameters:

  • event (string | string[]) — event name
  • handler (function) — callback
app.onFirst('cleaner:before:paste', (payload) => {
  payload.html = sanitize(payload.html);
  return payload;
});

once#

Subscribes to an event for a single emission, then unsubscribes automatically.

Parameters:

  • event (string | string[]) — event name
  • handler (function) — callback
app.once('editor:ready', () => loadSidePanel());

off#

Removes a previously registered handler.

Parameters:

  • event (string) — event name
  • handler (function) — same function reference passed to on
const onChange = () => sync();
app.on('blocks:change', onChange);
app.off('blocks:change', onChange);

emit#

Publishes an event. Each handler may return an updated payload object.

Parameters:

  • event (string) — event name
  • data (object, default {}) — payload

Returns: object — final payload after all handlers

app.emit('my-plugin:updated', { id: 42 });

emitWithStop#

Like emit, but returns whether any handler called stop().

Parameters:

  • event (string) — event name
  • data (object, default {}) — payload

Returns: { payload, stopped } — final payload and cancellation flag

const { stopped } = app.emitWithStop('upload:before:send', { url, body });
if (stopped) return;

emitAsync#

Runs async handlers sequentially and merges returned payloads.

Parameters:

  • event (string) — event name
  • data (object, default {}) — payload

Returns: Promise<object> — resolved final payload

const payload = await app.emitAsync('ai:before:send', { prompt });

getState#

Reads a value from the editor state store.

Parameters:

  • key (string) — dot-path key, e.g. 'theme.current'
  • fallback (any, optional) — value when key is missing

Returns: any — stored value or fallback

const mode = app.getState('theme.current', 'light');

setState#

Writes a state value and emits state:{key}.

Parameters:

  • key (string) — state key
  • value (any) — value to store
app.setState('sidebar.open', true);

hasState#

Parameters:

  • key (string) — state key

Returns: boolean — true when the key exists

if (app.hasState('draft.id')) restoreDraft();

isState#

Parameters:

  • key (string) — state key
  • value (any, default true) — value to compare

Returns: boolean — true when stored value equals value

if (app.isState('hostMode', 'iframe')) { /* … */ }

deleteState#

Parameters:

  • key (string) — state key to remove

Returns: boolean — whether the key was deleted

app.deleteState('temp.selection');

clearState#

Clears the entire state store.

app.clearState();

addState#

Adds an entry to a collection-style state key (object map).

Parameters:

  • key (string) — collection key
  • id (string) — entry id
  • value (any) — entry value

Returns: object — updated collection

app.addState('pins', 'intro', { offset: 120 });

mergeState#

Deep-merges an object into the state store and emits state:merge.

Parameters:

  • object (object) — partial state tree to merge
app.mergeState({ ui: { panel: 'open' } });

getLang#

Resolves a translated string by dot-path from i18n, with fallback to default English packs.

Parameters:

  • path (string) — key path, e.g. 'toolbar.save'
  • fallback (string, optional) — returned when key is missing

Returns: string — translated label

const label = app.getLang('toolbar.save', 'Save');

parseLang#

Replaces ## key ## placeholders in a string with getLang(key) values.

Parameters:

  • str (string) — string with language placeholders

Returns: string — resolved string (unchanged if not a string)

app.toast.show(app.parseLang('## autosave.saved ##'));

getOptions#

Returns: object — full merged options object for this instance

const opts = app.getOptions();

getOption#

Reads a single option by dot-path.

Parameters:

  • path (string) — option path, e.g. 'toolbar.buttons'
  • fallback (any, optional) — default when missing

Returns: any — option value

const buttons = app.getOption('toolbar.buttons', []);

isOption#

Checks that an option is set and not false, null, or undefined.

Parameters:

  • path (string) — option path

Returns: boolean — true when the option is enabled

if (app.isOption('autosave')) enableStatusIndicator();

setOption#

Sets an option at runtime by dot-path. Creates intermediate objects as needed.

Parameters:

  • path (string) — option path
  • value (any) — new value
app.setOption('ai.url', '/api/ai');

registerButton#

Registers or merges a toolbar/context button definition at runtime.

Parameters:

  • name (string) — button id
  • config (object) — button config (title, command, icon, etc.)

Returns: object | null — merged button config, or null when args are invalid

app.registerButton('export', {
  title: 'Export',
  command: 'output.save',
});

getModule#

Parameters:

  • name (string) — module key, e.g. 'block', 'toolbar'

Returns: object | undefined — module instance

const toolbar = app.getModule('toolbar');

getService#

Parameters:

  • name (string) — service key, e.g. 'selection', 'inserter'

Returns: object | undefined — service instance

const selection = app.getService('selection');

getPlugin#

Parameters:

  • key (string) — plugin instance key from plugins options

Returns: object | null — plugin instance, or null when not active

const anchor = app.getPlugin('anchor');
anchor?.openDialog();

isPluginActive#

Parameters:

  • key (string) — plugin instance key

Returns: boolean — true when the plugin is loaded

if (app.isPluginActive('review')) {
  app.getPlugin('review').openPanel();
}

invoke#

Calls a module or plugin method by command string (module.method).

Parameters:

  • command (string) — command id, e.g. 'toolbar.add', 'toast.show'
  • ...args (any) — arguments forwarded to the target method

Returns: any — return value of the target method, or undefined when not found

app.invoke('toast.show', 'Saved');
app.invoke('toolbar.add', 'custom', { title: 'Custom', command: 'myPlugin.run' });

registerModule#

Registers a custom module class on the editor instance. Usually done via Redactor.addModule and options.modules instead of calling this directly.

Parameters:

  • name (string) — module key exposed as app[name]
  • ModuleClass (class) — module constructor (app) => instance
app.registerModule('notes', NotesModule);
app.notes.init();