Skip to main content
Lumen Editor mounts onto any existing DOM element and turns it into a fully featured rich text surface. Under the hood, it combines a contenteditable region with an HTML sanitizer — every piece of content that enters or leaves the editor passes through an allowlist-based sanitization step, so what you get back is always clean, safe markup regardless of how the content arrived.

Creating an editor instance

You initialize the editor by calling the Editor constructor with a CSS selector (or DOM element reference) and an options object. The example below shows the most commonly used options together:
const editor = new Editor('#editor', {
  placeholder: 'Write here…',
  theme: 'light',            // 'light' | 'dark'
  locale: 'en',              // 'en' | 'tr' | custom
  value: '<p>Hello world</p>',
  toolbar: [
    ['undo', 'redo'],
    ['h1', 'h2', 'paragraph'],
    ['bold', 'italic', 'underline'],
    ['ul', 'ol'],
    ['link', 'image', 'code'],
    ['html']
  ],
  autoSave: { key: 'my-doc', debounce: 800 },
  uploadImage: async (file) => {
    const form = new FormData();
    form.append('file', file);
    const res = await fetch('/upload', { method: 'POST', body: form });
    return (await res.json()).url;
  }
});
The value option pre-populates the editor with existing HTML content. You can omit it to start with an empty document.

Reading content

Two methods let you read the current document out of the editor.
// Returns the current document as sanitized HTML
const html = editor.getHTML();
// e.g. '<p>Hello <strong>world</strong></p>'
Use getHTML() whenever you need to persist or render the content elsewhere. Use getText() when you need a markup-free string — for example, to count words or feed content into a search index.
Always call getHTML() to retrieve content rather than reading the DOM directly. The return value is sanitized HTML — the raw contenteditable DOM may contain intermediate editing artifacts that getHTML() normalizes away.

Setting content

You can replace the editor’s entire content programmatically at any time using setHTML(). The new value is sanitized before it is inserted, just like any other input.
editor.setHTML('<p>New content</p>');
This is useful when you want to load a different document into the editor — for example, after the user selects a saved draft from a list.

Listening to events

The editor emits events you can subscribe to with editor.on(event, fn). The two most useful events are change (fired on every edit) and error (fired when the sanitizer discards content):
// Fires after every user edit with the current sanitized HTML
editor.on('change', (html) => {
  save(html);
});

// Fires when content is discarded by the sanitizer
editor.on('error', (e) => {
  console.warn(e.code);
});
Subscribe to error events when you want observability into what the sanitizer is stripping — for example, to log unusual paste payloads — without surfacing that detail to the end user.

Toggling the HTML source view

Calling editor.toggleHtmlView() switches the editing surface between the rich text (WYSIWYG) view and a raw HTML source view. This is the same action triggered by the html toolbar button when it is included in your toolbar configuration.
// Toggle between rich text and raw HTML source view
editor.toggleHtmlView();
This is useful for programmatically switching modes — for example, opening the source view automatically when a user navigates to an advanced settings panel.

Extending with plugins

You can add custom commands, buttons, or behaviors to the editor by registering a plugin with editor.use(plugin). Plugins are plain objects or classes that follow the Lumen Editor plugin interface.
editor.use(myPlugin);
Call editor.use() before the editor renders its toolbar so that any custom commands defined by the plugin are available to include in the toolbar option. See the Plugin API reference for the full plugin interface.

Focusing the editor

To programmatically move the browser’s focus into the editing area — for example, immediately after mounting — call editor.focus():
editor.focus();

Cleaning up

When you no longer need the editor — for example, when a single-page application navigates away from the editing view — call destroy() to remove all event listeners and clean up the DOM:
editor.destroy();
Failing to call destroy() before removing the host element from the DOM can leave dangling event listeners attached to the document. Always pair destroy() with your framework’s unmount or cleanup lifecycle hook.

Content lifecycle

Every edit the user makes flows through the following steps before your application code sees it:
1

User types or pastes content

The user interacts with the contenteditable region. Pasted HTML is intercepted and sanitized before it is inserted into the document.
2

Change event fires

The editor emits a change event carrying the current sanitized HTML string. Subscribe with editor.on('change', (html) => { … }).
3

Your handler receives sanitized HTML

The html argument passed to the change callback is the same value you would get from calling editor.getHTML() — fully sanitized and ready to persist.
4

getHTML() returns the same safe output

At any point outside the event, calling editor.getHTML() returns the current sanitized document so you can read content on demand rather than only in response to changes.