Skip to main content
The Editor constructor mounts a fully functional WYSIWYG editor onto any DOM element you choose. You pass a target — either a CSS selector string or a direct element reference — and an optional configuration object to control everything from the initial theme to image upload handling.

Import

import { Editor } from 'lumen-editor';
import 'lumen-editor/theme.css';

const editor = new Editor(target, options);

Parameters

target
string | HTMLElement
required
The DOM node on which the editor mounts. Pass a CSS selector string (e.g. '#editor') or a direct HTMLElement reference. The constructor throws if the selector matches nothing or the element is null.
options
EditorOptions
An optional configuration object. All keys are optional — omitting the object entirely is valid and applies all defaults.

Options

placeholder
string
Ghost text displayed inside the editor when its content is empty. Rendered as a CSS ::before pseudo-element and is never included in getHTML() output.
theme
'light' | 'dark'
default:"'light'"
Sets the initial visual theme. You can switch the theme at runtime using setTheme().
locale
'en' | 'tr' | object
default:"'en'"
Controls the UI locale for built-in labels and tooltips. Pass 'en' or 'tr' to use a built-in locale, or supply your own translation object to override every string.
value
string
Initial HTML content to load into the editor on mount. The string is sanitized before rendering — the same pipeline used by setHTML().
toolbar
string[][]
Defines the toolbar layout as an array of groups, where each group is an array of command name strings. The order of groups and commands determines their left-to-right render order.
toolbar: [
  ['bold', 'italic', 'underline'],
  ['h1', 'h2', 'h3'],
  ['ul', 'ol'],
  ['link', 'image'],
]
autoSave
{ key: string, debounce: number }
Enables automatic saving of editor content to localStorage.
uploadImage
async (file: File) => string
An async callback invoked whenever the user inserts an image. Receives the selected File object and must return a URL string (local object URL, CDN URL, base64 data URI, etc.) that is inserted as the src of the <img> tag. If the callback throws or returns a falsy value, an UPLOAD_FAILED error event fires.
uploadImage: async (file) => {
  const form = new FormData();
  form.append('file', file);
  const res = await fetch('/api/upload', { method: 'POST', body: form });
  const { url } = await res.json();
  return url;
}
plugins
((editor: Editor) => void)[]
An array of plugin functions to install when the editor first mounts. Each function receives the fully initialized Editor instance. See the Plugin API for details.
modules
EditorModule[]
An array of module definitions for the toolbar — either built-in modules re-exported from lumen-editor or your own custom modules. See the Module API for details.
sanitize
SanitizeConfig
A custom allowlist configuration passed to the built-in HTML sanitizer. Use this to permit additional tags or attributes that the default policy strips.
sanitize: {
  allowedTags: ['mark', 'kbd'],
  allowedAttributes: { '*': ['data-id'] },
}
maxImageSize
number
default:"5242880"
Maximum allowed file size in bytes for image uploads. Defaults to 5 * 1024 * 1024 (5 MB). Files exceeding this limit are rejected before the uploadImage callback runs and fire an UPLOAD_TOO_LARGE error event.
allowedImageTypes
string[]
MIME types accepted during image upload. Files whose declared type is not in this list are rejected with an UPLOAD_INVALID_TYPE error. The editor also validates magic bytes to confirm the declared type matches the actual file content.

Full Example

The example below demonstrates every available option in a single constructor call:
import { Editor, modules } from 'lumen-editor';
import 'lumen-editor/theme.css';

const editor = new Editor('#editor', {
  // Appearance
  placeholder: 'Start writing…',
  theme: 'dark',
  locale: 'en',

  // Initial content
  value: '<p>Hello, <strong>world</strong>!</p>',

  // Toolbar layout — two groups
  toolbar: [
    ['bold', 'italic', 'underline', 'strikethrough'],
    ['h1', 'h2', 'h3', 'paragraph'],
    ['ul', 'ol', 'blockquote', 'code'],
    ['link', 'image', 'html'],
    ['undo', 'redo'],
  ],

  // Auto-save to localStorage
  autoSave: {
    key: 'my-editor-draft',
    debounce: 500,
  },

  // Image upload handler
  uploadImage: async (file) => {
    const form = new FormData();
    form.append('file', file);
    const res = await fetch('/api/upload', { method: 'POST', body: form });
    const { url } = await res.json();
    return url;
  },

  // Image constraints
  maxImageSize: 2 * 1024 * 1024,            // 2 MB
  allowedImageTypes: ['image/png', 'image/jpeg'],

  // Custom sanitizer allowlist
  sanitize: {
    allowedTags: ['mark'],
    allowedAttributes: { 'mark': ['class'] },
  },

  // Plugins
  plugins: [
    (editor) => {
      editor.on('change', (html) => console.log('Content changed:', html));
    },
  ],

  // Modules — mix built-ins and custom
  modules: [
    ...Object.values(modules),
    {
      name: 'highlight',
      group: 'inline',
      icon: '<span style="background:yellow">H</span>',
      label: 'Highlight',
      exec: (editor) => document.execCommand('backColor', false, 'yellow'),
    },
  ],
});
Always import lumen-editor/theme.css alongside the editor. Without it the toolbar and editor surface render without any styling.