Deep dives into tables, images, video, floating toolbar, block reordering, autosave, Find & Replace, and more.
Click the Insert → Table button. A dialog lets you configure:
<th> elementsRight-click any table cell to access:
| Action | Description |
|---|---|
| Insert Row Above | Add a row above the current cell |
| Insert Row Below | Add a row below the current cell |
| Insert Column Left | Add a column to the left |
| Insert Column Right | Add a column to the right |
| Delete Row | Remove the current row |
| Delete Column | Remove the current column |
| Delete Table | Remove the entire table |
| Merge Cells | Merge selected cells horizontally (colspan) |
| Split Cell | Split a previously merged cell back to individual cells |
[!TIP]
To select multiple cells for merging: click the first cell, holdShift, click the last cell in the same row, then right-click → Merge Cells.
Hover near the border between two columns — a vertical drag handle appears. Drag it to resize:
table-layout: fixed during resize<td> and <th> cellsTables are rendered with default styles from neiki-editor.css:
Neiki's Editor supports five ways to insert images:
Click Insert → Image, paste a URL. Inserted as a standard <img> tag.
The image dialog supports multiple file selection. All selected images are inserted sequentially.
imageUploadHandler: images are read via FileReader and embedded as base64 data URIsWith imageUploadHandler: each file is passed to your async handler, the returned URL is inserted as <img src="...">
:::javascript
new NeikiEditor('#editor', {
imageUploadHandler: async (file) => {
const formData = new FormData();
formData.append('image', file);
const res = await fetch('/api/upload', { method: 'POST', body: formData });
const data = await res.json();
return data.url;
}
});
[!TIP]
UsingimageUploadHandleris strongly recommended for production — it prevents bloated base64 content and enables browser caching.[!CAUTION]
WithoutimageUploadHandler, base64-encoded images significantly increase the HTML content size. For large images or production use, configure the upload handler.
Drag image files directly into the editor content area. The editor detects the drop, uploads or reads as base64, and inserts each image at the drop position.
Copy an image to your clipboard (screenshot, right-click → Copy Image) and paste with Ctrl+V. Works with or without imageUploadHandler.
Click any image to select it. Resize handles appear on all four corners (NW, NE, SW, SE):
640 × 480) appears below the image while resizingWhen an image is selected, a contextual toolbar appears:
| Button | Description |
|---|---|
| ⠿ Drag handle | Click and drag to reposition the image |
| Replace | Open file picker to swap the current image |
| Delete | Remove the selected image |
[!NOTE]
The floating text-formatting toolbar is automatically hidden when an image is selected — only image-specific actions are shown.
Insert videos via Insert → Video:
videoUploadHandlerDrag & drop — drag a video file into the editor
:::javascript
new NeikiEditor('#editor', {
videoUploadHandler: async (file) => {
const formData = new FormData();
formData.append('video', file);
const response = await fetch('/api/upload-video', { method: 'POST', body: formData });
const data = await response.json();
return data.url;
}
});
Inserted videos render as <video controls> elements. They can be resized and repositioned just like images.
Four built-in themes:
| Theme | Key | Description |
|---|---|---|
| Light | 'light' |
Clean white background, dark text. Default. |
| Dark | 'dark' |
Dark background, light text. Easy on the eyes. |
| Blue | 'blue' |
Bright blue interface, white canvas. |
| Dark Blue | 'dark-blue' |
Deep blue interface, blue accents. |
At initialization:
new NeikiEditor('#editor', { theme: 'dark' });
Programmatically:
editor.setTheme('dark-blue');
editor.toggleTheme(); // cycle: light → dark → blue → dark-blue → light
Via the More menu (⋯): The Change theme select lets users pick any theme.
[!IMPORTANT]
The selected theme is persisted tolocalStorageas a global setting. This means:
- It applies to all editor instances on the page
- It persists across page reloads
- If the user selected dark mode, it remains dark even if you settheme: 'light'in config — user preference always takes priority
The dark theme applies the CSS class neiki-dark to the editor container. Target it for custom dark-mode styles:
.neiki-dark .my-custom-element {
background: #1e1e1e;
color: #e0e0e0;
}
| Code | Language |
|---|---|
en |
English (default) |
cs |
Czech |
zh |
Chinese |
es |
Spanish |
de |
German |
fr |
French |
pt |
Portuguese |
ja |
Japanese |
new NeikiEditor('#editor', {
language: 'cs'
});
Override any translation key via the translations option:
new NeikiEditor('#editor', {
language: 'en',
translations: {
'toolbar.bold': 'Make Bold',
'placeholder': 'Start writing here...'
}
});
[!NOTE]
Thelanguageoption must be set at initialization. Changing it at runtime requires re-initializing the editor.
Open via the findReplace toolbar button. The bar appears at the top of the editor content area.
| Feature | Description |
|---|---|
| Search field | Type text to find |
| Replace field | Type replacement text |
| Case Sensitive | Toggle — when active, Hello ≠ hello |
| Regex Mode | Toggle — enables JS RegExp patterns |
| Find Next | Jump to and highlight the next match |
| Replace | Replace the current highlighted match |
| Replace All | Replace all occurrences at once |
| Pattern | Matches |
|---|---|
\b\w+\b |
Every word |
\d{4} |
4-digit numbers |
https?://\S+ |
URLs |
<em>.*?</em> |
Italic-wrapped text |
Autosave is accessible via the More menu (⋯).
localStorage on every changeAutosave storage is scoped to page URL + editor identity by default. For isolation across records on the same URL, use autosaveKey:
new NeikiEditor('#editor', {
autosaveKey: 'article-42'
});
[!CAUTION]
Autosave is designed for development and draft recovery. For production, useonSaveoronChangecallbacks to save to your backend:
javascript new NeikiEditor('#editor', { onChange: debounce(function(content) { fetch('/api/save', { method: 'POST', body: JSON.stringify({ content }) }); }, 2000) });
A context-sensitive toolbar that appears automatically when text is selected.
| Position | Buttons | Description |
|---|---|---|
| Left | ▲ ▼ | Move current block up / down |
| Right | B I U |
Bold, Italic, Underline, Strikethrough, Link |
[!NOTE]
The floating toolbar is always enabled and cannot be disabled or customized through config.
Hover over any content block to reveal a grip handle (⠿) on the left margin:
Undo/Redo records block moves. onChange fires after each move.
[!TIP]
You can also use the ▲ ▼ buttons in the floating toolbar for keyboard-friendly block reordering.
The status bar sits at the bottom of the editor:
| Position | Content |
|---|---|
| Left | Word count and character count |
| Right | Autosave status (when enabled) and current block type (p, h1, h2, h3, etc.) |
Updates automatically as you type or move the cursor.
Click More → Print to print the editor content:
The printed output includes only the content — no toolbar, status bar, or editor chrome.
| ⚙️ Configuration | All config options including imageUploadHandler, autosaveKey |
| 🎨 Themes & Styling | CSS customization and theme details |
| 📋 API Reference | setTheme, toggleTheme, insertHTML and all methods |
| 🔒 Security | Sanitization details |