Redactor 4 Configuration Guide
Last Updated: January 2026
Related Files:
client/js/crm/editors/redactor4.js- Base configurations and pluginsapp/javascript/controllers/redactor4_init_controller.js- Stimulus initializationapp/inputs/redactor_input.rb- SimpleForm custom input
Overview
Section titled “Overview”Redactor 4 is the WYSIWYG editor used throughout the CRM for rich text editing. It supports multiple modes depending on the use case, from full-featured blog editing to minimal note-taking.
Editor Modes Comparison
Section titled “Editor Modes Comparison”| Feature | Blog | Default | Air (Notes) | Readonly | |
|---|---|---|---|---|---|
| Base Options | defaultRedactor4Options + aiRedactor4Options | emailRedactor4Options | defaultRedactor4Options | simpleNotesRedactor4Options | Any + disabled |
| Min Height | 2000px | 500px | 300px | 100px | Inherited |
| Pathbar | Hidden | Hidden | Hidden | Hidden | Hidden |
| Source Code | Via data attr | Via data attr | Via data attr | No | No |
| Toolbar | External (#redactor-blog-toolbar) | Sticky (72px offset) | Sticky (72px offset) | Air (floating) | Hidden |
| CSS Injection | WWW styles | CodeMirror custom CSS | None | None | None |
| AI Tools | ✅ | ❌ | ❌ | ❌ | ❌ |
| Context Menu | ✅ | ❌ | ✅ | ❌ | ❌ |
Plugin Availability by Mode
Section titled “Plugin Availability by Mode”| Plugin | Blog | Default | Air | Description | |
|---|---|---|---|---|---|
| alignment | ✅ | ✅ | ✅ | ❌ | Text alignment |
| counter | ✅ | ✅ | ✅ | ❌ | Word/character count |
| fullscreen | ✅ | ✅ | ✅ | ❌ | Fullscreen editing |
| imageresize | ✅ | ❌ | ✅ | ❌ | Visual image resizing |
| fontcolor | ✅ | ✅ | ✅ | ❌ | Text color |
| fontfamily | ✅ | ✅ | ✅ | ❌ | Font family |
| fontsize | ✅ | ✅ | ✅ | ❌ | Font size |
| blockcolor | ✅ | ✅ | ✅ | ❌ | Block text color |
| blockbackground | ✅ | ✅ | ✅ | ❌ | Block background |
| blockborder | ✅ | ✅ | ✅ | ❌ | Block borders |
| blockfontsize | ✅ | ✅ | ✅ | ❌ | Block font size |
| wyimage | ✅ | ✅ | ✅ | ❌ | WY Image Library picker |
| wyembed | ✅ | ❌ | ✅ | ❌ | oEmbed (YouTube, etc.) |
| wyvideo | ✅ | ❌ | ❌ | ❌ | WY Video Library picker |
| wyfaq | ✅ | ❌ | ❌ | ❌ | WY FAQ Library picker |
| ai | ✅ | ❌ | ❌ | ❌ | OpenAI text/image tools |
| mergetag | ❌ | ✅ | ❌ | ❌ | Liquid merge tags |
| clips | ❌ | ✅ | ❌ | ❌ | Email snippets |
| variable | ❌ | ✅ | ❌ | ❌ | Variable insertion |
| ❌ | ✅ | ❌ | ❌ | Email formatting | |
| wyemailblocks | ❌ | ✅ | ❌ | ❌ | WY Header/Footer blocks |
Mode Detection Logic
Section titled “Mode Detection Logic”The Stimulus controller (redactor4_init_controller.js) detects which mode to use:
// In initializeRedactor4()const isEmailEditor = editor.id === 'redactor-email-template-body-v4' || (this.hasEmailValue && this.emailValue);const isBlogEditor = (this.hasBlogValue && this.blogValue) || editor.id === 'redactor-blog';const isAirMode = this.hasAirValue && this.airValue;Priority Order:
Section titled “Priority Order:”- Air Mode -
data-redactor4-init-air-value="true" - Email Mode -
editor.id === 'redactor-email-template-body-v4'ORdata-redactor4-init-email-value="true" - Blog Mode -
editor.id === 'redactor-blog'ORdata-redactor4-init-blog-value="true" - Default Mode - Fallback
Usage Examples
Section titled “Usage Examples”1. Blog Editor (Full Featured)
Section titled “1. Blog Editor (Full Featured)”Used in: app/views/crm/posts/_content.html.erb
<div data-controller="redactor4-init" data-redactor4-init-blog-value="true" data-redactor4-init-source-value="<%= current_user&.admin? %>"> <%= f.input_field :solution, id: 'redactor-blog', class: 'form-control', data: { redactor4_init_target: 'editor', www_css: webpack_css_url('www').to_json } %></div>Blog-specific features:
- External toolbar in sticky header (
#redactor-blog-toolbar) - WWW CSS injected for WYSIWYG preview
- 2000px minimum height
- AI tools, FAQ picker, Video picker enabled
blog-post-bodyclass applied for styling
2. Email Template Editor
Section titled “2. Email Template Editor”Used in: app/views/email_templates/_form.html.erb
<div data-controller="redactor4-init" data-redactor4-init-email-value="true"> <%= f.text_area :body, id: 'redactor-email-template-body-v4', class: 'form-control', data: { redactor4_init_target: 'editor' } %></div>Email-specific features:
- Liquid merge tags (recipient, sender, etc.)
- Email clips (header, footer snippets)
- WY Email Blocks plugin
- Custom CSS injection from CodeMirror
- Paste converts to plain text
3. Default Editor (Standard)
Section titled “3. Default Editor (Standard)”Used in: Most forms via SimpleForm input
<%= f.input :description, as: :redactor %>Or manually:
<div data-controller="redactor4-init"> <%= f.text_area :body, class: 'form-control', data: { redactor4_init_target: 'editor' } %></div>4. Air Mode (Minimal Notes)
Section titled “4. Air Mode (Minimal Notes)”Used in: Activity notes, comments
<div data-controller="redactor4-init" data-redactor4-init-air-value="true"> <%= f.text_area :notes, class: 'form-control', data: { redactor4_init_target: 'editor' } %></div>Air mode features:
- Floating toolbar (appears on selection)
- Minimal buttons: bold, italic, deleted, list
- No plugins loaded
- Plain text paste
5. Readonly Preview
Section titled “5. Readonly Preview”Any mode can be made readonly:
<div data-controller="redactor4-init" data-redactor4-init-readonly-value="true"> <%= f.text_area :preview, class: 'form-control', data: { redactor4_init_target: 'editor' } %></div>Stimulus Controller Values
Section titled “Stimulus Controller Values”| Value | Type | Description |
|---|---|---|
blog | Boolean | Enable blog mode with AI, FAQ, Video plugins |
email | Boolean | Enable email mode with merge tags |
air | Boolean | Enable minimal air mode (floating toolbar) |
minHeight | String | Override minimum height (e.g., “500px”) |
plugins | Array | Override plugin list |
source | Boolean | Enable HTML source editing (admin only) |
readonly | Boolean | Disable editing, hide toolbar |
legacyBody | String | Legacy v3 content for migration |
Custom WY Plugins
Section titled “Custom WY Plugins”WY Image (wyimage)
Section titled “WY Image (wyimage)”Image picker that integrates with the Image Library. Uses oEmbed API for rich HTML insertion.
Features:
- Image search and selection
- Visual cropping with Cropper.js
- All ImageKit transformations (resize, rotate, blur, etc.)
- Responsive srcset generation
- Caption support
- Re-editing existing images
Inserted HTML structure:
<figure class="wy-image-embed" data-wy-image-id="123" data-wy-image-options="{...}"> <img src="..." srcset="..." alt="..." loading="lazy" class="img-fluid"> <figcaption class="figure-caption">Caption here</figcaption></figure>WY Video (wyvideo)
Section titled “WY Video (wyvideo)”Video picker that integrates with the Video Library. Uses oEmbed API.
Blog only - Not available in email or default modes.
WY FAQ (wyfaq)
Section titled “WY FAQ (wyfaq)”FAQ picker that embeds FAQ accordion blocks. Uses oEmbed API.
Blog only - Not available in email or default modes.
WY Embed (wyembed)
Section titled “WY Embed (wyembed)”Enhanced oEmbed for external content (YouTube, Vimeo, etc.).
Not available in email mode - Email clients don’t support iframes.
WY Email Blocks (wyemailblocks)
Section titled “WY Email Blocks (wyemailblocks)”Quick insertion of branded email header/footer.
Email only - Not available in other modes.
Configuration Files
Section titled “Configuration Files”Base Configurations (redactor4.js)
Section titled “Base Configurations (redactor4.js)”// Exported configurations:window.defaultRedactor4Options // Standard editorwindow.emailRedactor4Options // Email templateswindow.aiRedactor4Options // AI + wyfaq + wyvideo (merged for blog)window.simpleNotesRedactor4Options // Air modePaste Settings
Section titled “Paste Settings”Default/Blog Mode:
clean: true- Sanitize for XSS protectionplaintext: false- Keep HTML formattingstripAttr.allowedClasses- Whitelist of Bootstrap 5.3 + blog classesstripAttr.allowedAttributes- Safe attributes only (nostyle)
Email Mode:
plaintext: true- Convert to plain text
Air Mode:
plaintext: true- Convert to plain text
CSS Class Handling
Section titled “CSS Class Handling”The paste settings include a whitelist of allowed CSS classes for security:
- Blog classes:
blogLeft,blogRight,blog-cta,blog-post-body, etc. - Bootstrap 5.3: Spacing, display, flexbox, text, colors, tables, etc.
- Redactor alignment:
wrap-center,wrap-left,wrap-right, etc.
See defaultRedactor4Options.paste.stripAttr.allowedClasses for full list.
Troubleshooting
Section titled “Troubleshooting”Editor not initializing
Section titled “Editor not initializing”- Check browser console for errors
- Verify Stimulus controller is connected:
📝 Redactor4 Stimulus controller connected - Check if element has correct data attributes
- Verify lazy loading:
📝 Redactor 4 module loaded
Toolbar missing
Section titled “Toolbar missing”- For blog: Check
#redactor-blog-toolbarexists in DOM - For email/default: Check
toolbar.stickyTopOffsetis correct (72px for CRM navbar) - For readonly: Toolbar is intentionally hidden
Plugins not working
Section titled “Plugins not working”- Check plugin is in the correct options set
- Check browser console for plugin errors
- Verify plugin JS is imported in
redactor4.js
Images not cropping correctly
Section titled “Images not cropping correctly”- Verify
Oembed::ImageProvideris handling crop params - Check that crop dimensions aren’t being upscaled beyond their size
- Verify ImageKit transformation string is correct
Related Documentation
Section titled “Related Documentation”- Stimulus Controllers
- Asset Build Workflow
- Redactor Stimulus Migration