
It attaches to any textarea field and works with any backend stack that can read a standard form POST.
Features
- Type
/anywhere in the editor to open a command palette. - Displays a Floating Editor Toolbar on text selection.
- A hover handle on each block lets you reorder content by dragging. Touch devices support long-press to drag.
- Supports Markdown syntax like
#,##,###,-,*,1.,>,!, or---. - Supports drag-and-drop image upload, clipboard paste, gallery browsing, base64 auto-upload, and per-image attribute editing.
- Insert and manage tables with row and column controls via a context menu.
- Themeable via CSS Variables.
- Supports 20+ languages with automatic RTL detection for Arabic and Hebrew.
- Pasted content is sanitized on input. Dangerous tags, inline event handlers,
javascript:URLs, and unlisted CSS classes are stripped. - A built-in search panel with match navigation and replace functionality.
- Unlimited Undo/Redo history
- Fullscreen Mode with a single toggle.
- Real-time Word/Character Counter displayed in the editor footer.
- Switch to raw HTML editing with syntax highlighting at any time.
How To Use It:
1. Add the stylesheet and import the main class in a type="module" script block:
<!-- Load the editor styles -->
<link rel="stylesheet" href="/redactix/Redactix.css">
<script type="module">
// Import the Redactix class as an ES module
import Redactix from '/redactix/Redactix.js';
// Initialize on all textareas matching the selector
new Redactix({
selector: '.article-editor'
});
</script>
2. Redactix replaces any textarea matching the selector. Pre-populate it with HTML content if needed:
<!-- Redactix attaches to this element and replaces it with the editor UI --> <textarea class="article-editor"> <h1>Getting Started</h1> <p>Your initial content goes here.</p> </textarea>
3. The package includes a ready-made PHP script (redactix_images.php) for upload, browse, and delete operations. Point the editor at it with two options:
The upload endpoint expects a multipart POST and returns a JSON object with
success,src,srcset,alt,title, andcaption. The browse endpoint returns a JSON array of image objects. The delete endpoint acceptsaction=delete&file=filename.jpgand returns a success flag.For local development, swap in
redactix_images_demo.php. It returns a placeholder image on every upload so you can test the full gallery flow.
new Redactix({
selector: '.article-editor',
// POST endpoint for new file uploads
uploadUrl: '/redactix_images.php',
// POST endpoint for gallery browsing
browseUrl: '/redactix_images.php',
// Enables delete buttons in the gallery UI
allowImageDelete: true
});
4. For comment forms or user-generated content areas, enable lite mode. Upload features are off and links get automatic nofollow:
new Redactix({
selector: '.comment-box',
liteMode: true
});
5. All configuration options.
selector(string): CSS selector targeting the textarea elements to initialize. Required.locale(string): Language code for UI text. Defaults to'en'. Accepts any of the 20+ supported codes ('fr','de','ru','ar','he', etc.). RTL is detected automatically from the locale.uploadUrl(string): URL of the server endpoint that handles image file uploads via multipart POST.browseUrl(string): URL of the server endpoint that returns the list of previously uploaded images.allowImageDelete(boolean): Shows delete buttons in the image gallery. Defaults tofalse.maxHeight(string): Sets a CSS max-height on the editor content area. Accepts any valid CSS length value such as'500px'. The sticky toolbar behavior is disabled when this option is set.classes(array): Array of CSS class strings available for quick selection in the element Attributes dialog.liteMode(boolean): Activates the stripped-down editor mode suited to comment forms and forums. Defaults tofalse.theme(string): Applies a theme class at initialization. Accepts'light','dark', or'auto'.calloutPresets(array): Array of objects defining custom callout (aside) styles. Each object takesname,label, andclasskeys.quotePresets(array): Array of objects defining custom blockquote styles. Each object takesname,label, andclasskeys.
6. API methods.
const textarea = document.querySelector('#main-editor');
// Returns the editor's current HTML as a clean string.
// Editor-internal wrapper elements are stripped from the output.
const html = textarea.redactix.getContent();
// Replaces all editor content with new HTML.
// This re-initializes all block elements and resets the undo/redo stack.
textarea.redactix.setContent('<h2>Updated Section</h2><p>New body copy here.</p>');
// Forces an immediate sync of editor content to the underlying textarea value.
// The editor syncs automatically on every change, but this call
// is useful just before programmatic form submission.
textarea.redactix.sync();
console.log(textarea.value); // Logs the current HTML string
// Changes the active theme at runtime.
// Accepts 'light', 'dark', or 'auto'.
textarea.redactix.setTheme('dark');
// Copy content between two editor instances.
// Direct textarea.value assignment does not work with Redactix.
// Use getContent() and setContent() across instances.
const source = document.querySelector('#source-editor');
const target = document.querySelector('#target-editor');
target.redactix.setContent(source.redactix.getContent());
7. Type / at any point in the editor to open the command menu. Navigate with arrow keys and press Enter to insert.
| Command | Inserts |
|---|---|
/h1 |
Heading 1 |
/h2 |
Heading 2 |
/h3 |
Heading 3 |
/quote |
Blockquote |
/callout |
Callout/aside block |
/code |
Code block |
/image |
Image dialog |
/youtube |
YouTube embed |
/table |
Table |
/hr |
Horizontal rule |
/ol |
Numbered list |
/ul |
Bullet list |
8. Keyboard shortcuts.
| Shortcut | Action |
|---|---|
Ctrl+B |
Bold |
Ctrl+I |
Italic |
Ctrl+U |
Underline |
Ctrl+Z |
Undo |
Ctrl+Y |
Redo |
Ctrl+F |
Find & Replace |
Escape |
Exit fullscreen |
9. Override the default CSS variables to create your own editor themes.
/* ================================
Variables - Light Theme (Default)
================================ */
:root {
/* Primary colors */
--redactix-primary: #2563eb;
--redactix-primary-hover: #1d4ed8;
--redactix-primary-light: #dbeafe;
--redactix-primary-rgb: 37, 99, 235;
/* Danger colors */
--redactix-danger: #dc2626;
--redactix-danger-hover: #b91c1c;
--redactix-danger-light: #fef2f2;
/* Base colors */
--redactix-border: #e5e7eb;
--redactix-bg: #ffffff;
--redactix-bg-secondary: #f9fafb;
--redactix-bg-hover: #f3f4f6;
--redactix-bg-active: #e5e7eb;
--redactix-text: #374151;
--redactix-text-muted: #6b7280;
--redactix-text-placeholder: #9ca3af;
/* UI elements */
--redactix-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
--redactix-radius: 6px;
--redactix-overlay: rgba(0, 0, 0, 0.4);
/* Content elements */
--redactix-blockquote-bg: #f8fafc;
--redactix-code-bg: #f3f4f6;
--redactix-code-color: #e11d48;
--redactix-mark-bg: #fef08a;
--redactix-spoiler-bg: #374151;
/* Code editor (always dark) */
--redactix-code-editor-bg: #1e1e1e;
--redactix-code-editor-gutter: #252526;
--redactix-code-editor-text: #d4d4d4;
--redactix-code-editor-line: #858585;
--redactix-code-editor-selection: #264f78;
/* Pre blocks */
--redactix-pre-bg: #1f2937;
--redactix-pre-text: #e5e7eb;
/* Floating toolbar (always dark) */
--redactix-floating-bg: #1f2937;
--redactix-floating-text: #e5e7eb;
--redactix-floating-separator: rgba(255, 255, 255, 0.2);
/* Callouts - these are semantic and usually stay the same */
--redactix-callout-bg: #f3f4f6;
--redactix-callout-border: #d1d5db;
--redactix-callout-text: #374151;
/* Find highlight */
--redactix-find-highlight: #fef08a;
--redactix-find-current: #f97316;
/* Drag states */
--redactix-drag-bg: #dbeafe;
--redactix-dragover-bg: #eff6ff;
}
/* ================================
Dark Theme
================================ */
.redactix-wrapper.redactix-dark {
/* Primary colors - slightly brighter for dark mode */
--redactix-primary: #3b82f6;
--redactix-primary-hover: #60a5fa;
--redactix-primary-light: #1e3a5f;
--redactix-primary-rgb: 59, 130, 246;
/* Danger colors */
--redactix-danger: #ef4444;
--redactix-danger-hover: #f87171;
--redactix-danger-light: #3f1d1d;
/* Base colors */
--redactix-border: #374151;
--redactix-bg: #1f2937;
--redactix-bg-secondary: #111827;
--redactix-bg-hover: #374151;
--redactix-bg-active: #4b5563;
--redactix-text: #f3f4f6;
--redactix-text-muted: #9ca3af;
--redactix-text-placeholder: #6b7280;
/* UI elements */
--redactix-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
--redactix-overlay: rgba(0, 0, 0, 0.6);
/* Content elements */
--redactix-blockquote-bg: #111827;
--redactix-code-bg: #374151;
--redactix-code-color: #fb7185;
--redactix-mark-bg: #854d0e;
--redactix-spoiler-bg: #e5e7eb;
/* Pre blocks */
--redactix-pre-bg: #111827;
--redactix-pre-text: #e5e7eb;
/* Callouts - darker versions */
--redactix-callout-bg: #374151;
--redactix-callout-border: #4b5563;
--redactix-callout-text: #f3f4f6;
/* Find highlight */
--redactix-find-highlight: #854d0e;
--redactix-find-current: #ea580c;
/* Drag states */
--redactix-drag-bg: #1e3a5f;
--redactix-dragover-bg: #1e3a5f;
}
/* Dark theme via prefers-color-scheme (auto mode) */
@media (prefers-color-scheme: dark) {
.redactix-wrapper.redactix-auto {
/* Primary colors */
--redactix-primary: #3b82f6;
--redactix-primary-hover: #60a5fa;
--redactix-primary-light: #1e3a5f;
--redactix-primary-rgb: 59, 130, 246;
/* Danger colors */
--redactix-danger: #ef4444;
--redactix-danger-hover: #f87171;
--redactix-danger-light: #3f1d1d;
/* Base colors */
--redactix-border: #374151;
--redactix-bg: #1f2937;
--redactix-bg-secondary: #111827;
--redactix-bg-hover: #374151;
--redactix-bg-active: #4b5563;
--redactix-text: #f3f4f6;
--redactix-text-muted: #9ca3af;
--redactix-text-placeholder: #6b7280;
/* UI elements */
--redactix-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
--redactix-overlay: rgba(0, 0, 0, 0.6);
/* Content elements */
--redactix-blockquote-bg: #111827;
--redactix-code-bg: #374151;
--redactix-code-color: #fb7185;
--redactix-mark-bg: #854d0e;
--redactix-spoiler-bg: #e5e7eb;
/* Pre blocks */
--redactix-pre-bg: #111827;
--redactix-pre-text: #e5e7eb;
/* Callouts */
--redactix-callout-bg: #374151;
--redactix-callout-border: #4b5563;
--redactix-callout-text: #f3f4f6;
/* Find highlight */
--redactix-find-highlight: #854d0e;
--redactix-find-current: #ea580c;
/* Drag states */
--redactix-drag-bg: #1e3a5f;
--redactix-dragover-bg: #1e3a5f;
}
}
Alternatives:
The post Notion-Like Vanilla JS WYSIWYG Editor – Redactix appeared first on CSS Script.
Discover more from RSS Feeds Cloud
Subscribe to get the latest posts sent to your email.
