Skip to main content
This guide walks you through everything you need to go from a blank project to a fully functional rich text editor. By the end you will have Lumen Editor installed, mounted on a page, configured with real options, and wired up to read content and respond to changes.

Prerequisites

Before you begin, make sure you have the following in place:
  • A modern browser (Chrome 90+, Firefox 88+, Safari 14+, or Edge 90+) for the runtime environment.
  • Node.js 16+ and npm (or yarn / pnpm) if you plan to install via a package manager. You can skip this requirement entirely if you prefer the CDN approach.
No build step is required. If you just want to try Lumen Editor immediately, load it straight from a <script type="module"> tag pointing at the CDN bundle — no Node.js needed. See the Installation page for the full CDN snippet.

Steps

1

Install Lumen Editor

Add the package to your project using your preferred package manager.
npm install lumen-editor
Then import the editor class and its stylesheet at the top of your entry file. The stylesheet import is required — it provides the toolbar styles and theme variables.
import { Editor } from 'lumen-editor';
import 'lumen-editor/theme.css';
2

Add an HTML container

Lumen Editor mounts into any existing element on your page. Add a <div> (or any block element) with an id that you will pass to the constructor. Give it a minimum height so it is visible before the user starts typing.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My Editor</title>
  </head>
  <body>
    <div id="editor"></div>

    <script type="module" src="./main.js"></script>
  </body>
</html>
3

Initialize the editor with options

Create a new Editor instance, passing your container selector as the first argument and an options object as the second. The example below demonstrates the full set of supported options so you can pick the ones relevant to your use case.
import { Editor } from 'lumen-editor';
import 'lumen-editor/theme.css';

const editor = new Editor('#editor', {
  // Placeholder text shown when the editor is empty
  placeholder: 'Write here…',

  // Initial theme: 'light' (default) or 'dark'
  theme: 'light',

  // Locale for toolbar tooltips and ARIA labels
  locale: 'en',          // 'en' | 'tr' | custom locale object

  // Pre-populate the editor with existing HTML content
  value: '<p>Hello world</p>',

  // Toolbar layout — each nested array becomes a button group
  toolbar: [
    ['undo', 'redo'],
    ['h1', 'h2', 'paragraph'],
    ['bold', 'italic', 'underline'],
    ['ul', 'ol'],
    ['link', 'image', 'code'],
    ['html'],
  ],

  // Persist content to localStorage automatically
  autoSave: {
    key: 'my-doc',      // localStorage key
    debounce: 800,      // milliseconds to wait after last keystroke
  },

  // Async handler called when the user inserts an image from disk.
  // Return the URL that should appear in the <img src> attribute.
  uploadImage: async (file) => {
    const form = new FormData();
    form.append('file', file);
    const res = await fetch('/api/upload', { method: 'POST', body: form });
    return (await res.json()).url;
  },

  // Maximum allowed image file size in bytes (default: no limit)
  maxImageSize: 5 * 1024 * 1024,  // 5 MB

  // Restrict uploads to specific MIME types
  allowedImageTypes: ['image/jpeg', 'image/png', 'image/webp'],

  // Override the built-in sanitizer allowlist with a custom configuration
  sanitize: {
    allowedTags: ['p', 'strong', 'em', 'u', 'a', 'ul', 'ol', 'li', 'h1', 'h2', 'img'],
    allowedAttributes: { a: ['href', 'rel', 'target'], img: ['src', 'alt'] },
  },

  // Register plugins at construction time (same as calling editor.use() later)
  plugins: [],

  // Low-level module overrides for advanced customisation
  modules: {},
});
Every option is optional. Calling new Editor('#editor', {}) is perfectly valid and gives you a working editor with sensible defaults.
4

Listen for changes and read content

Subscribe to the change event to react whenever the user edits the document. Use getHTML() to retrieve sanitized HTML or getText() for plain text.
// React to every content change
editor.on('change', (html) => {
  console.log('Current HTML:', html);
  // e.g. auto-save to your backend
  save(html);
});

// Read content on demand
const html = editor.getHTML();   // sanitized HTML string
const text = editor.getText();   // plain text string

// Replace the entire content programmatically
editor.setHTML('<p>New content loaded from the server</p>');

// Switch theme at runtime
editor.setTheme('dark');

// Move focus into the editor programmatically
editor.focus();

// Install a plugin after construction
editor.use((editorInstance) => {
  // plugins receive the editor instance and can hook into its API
  editorInstance.on('change', () => console.log('plugin: content changed'));
});

// Clean up when your component or page unmounts
editor.destroy();
You can also listen for other built-in events:
EventFired when
changeThe document content changes
selectionchangeThe cursor or selection moves
history:changeThe undo/redo stack updates
view:toggleThe editor switches between WYSIWYG and raw HTML view
autosaveAn auto-save write completes
errorAn internal error occurs (receives an object with a code property)

What’s Next?

You now have a working Lumen Editor instance. From here you can:
  • Explore all install methods (yarn, pnpm, CDN) on the Installation page.
  • Learn how to extend the editor with the plugin system by writing a simple (editor) => { ... } function.
  • Tighten security or customise the sanitizer allowlist for your content requirements.