> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lumen.bjanczak.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lumen Editor Constructor: new Editor(target, options)

> Complete reference for the Editor constructor signature, the target parameter, and all constructor options with their types, defaults, and descriptions.

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

<CodeGroup>
  ```js JavaScript theme={null}
  import { Editor } from 'lumen-editor';
  import 'lumen-editor/theme.css';

  const editor = new Editor(target, options);
  ```

  ```ts TypeScript theme={null}
  import { Editor, EditorOptions } from 'lumen-editor';
  import 'lumen-editor/theme.css';

  const editor = new Editor(target, options);
  ```
</CodeGroup>

## Parameters

<ParamField path="target" type="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`.
</ParamField>

<ParamField path="options" type="EditorOptions">
  An optional configuration object. All keys are optional — omitting the object entirely is valid and applies all defaults.
</ParamField>

## Options

<ParamField body="placeholder" type="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.
</ParamField>

<ParamField body="theme" type="'light' | 'dark'" default="'light'">
  Sets the initial visual theme. You can switch the theme at runtime using [`setTheme()`](/api/methods#settheme).
</ParamField>

<ParamField body="locale" type="'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.
</ParamField>

<ParamField body="value" type="string">
  Initial HTML content to load into the editor on mount. The string is sanitized before rendering — the same pipeline used by `setHTML()`.
</ParamField>

<ParamField body="toolbar" type="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.

  ```js theme={null}
  toolbar: [
    ['bold', 'italic', 'underline'],
    ['h1', 'h2', 'h3'],
    ['ul', 'ol'],
    ['link', 'image'],
  ]
  ```
</ParamField>

<ParamField body="autoSave" type="{ key: string, debounce: number }">
  Enables automatic saving of editor content to `localStorage`.

  <Expandable title="autoSave properties">
    <ParamField body="key" type="string" required>
      The `localStorage` key under which content is stored.
    </ParamField>

    <ParamField body="debounce" type="number" required>
      Milliseconds to wait after the last change before writing to storage. Lower values save more frequently; higher values reduce I/O.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="uploadImage" type="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.

  ```js theme={null}
  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;
  }
  ```
</ParamField>

<ParamField body="plugins" type="((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](/api/plugins) for details.
</ParamField>

<ParamField body="modules" type="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](/api/modules) for details.
</ParamField>

<ParamField body="sanitize" type="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.

  ```js theme={null}
  sanitize: {
    allowedTags: ['mark', 'kbd'],
    allowedAttributes: { '*': ['data-id'] },
  }
  ```
</ParamField>

<ParamField body="maxImageSize" type="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.
</ParamField>

<ParamField body="allowedImageTypes" type="string[]" default="['image/png','image/jpeg','image/gif','image/webp']">
  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.
</ParamField>

## Full Example

The example below demonstrates every available option in a single constructor call:

```js theme={null}
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'),
    },
  ],
});
```

<Note>
  Always import `lumen-editor/theme.css` alongside the editor. Without it the toolbar and editor surface render without any styling.
</Note>
