Summary
JSON-first rich text editor built on FilamentRichEditor / TipTap — premium shell, Gravity icons, content limits with live feedback, responsive image pipeline, optional Spatie Media Library, YouTube embeds, block images, editor image overlay, fullscreen, autosave, paste cleanup, and keyboard-accessible toolbar.
Scope of this doc: only package-specific APIs (variant(),imageVariants(),youtube(), toolbar role presets,FlexRichContentRenderer, etc.). Everything else comes from FilamentRichEditor— see Filament Rich Editor.
Quick start
makeFlexRichContentRenderer() (see Rendering HTML).
Configuration catalog (package API)
FlexRichEditor-specific options only. The field extends FilamentRichEditor; inherited Filament APIs are not duplicated here.
Shell & field chrome
Content limits & footer
Editor UX
Toolbar
Static helpers (presets):
getFlexDefaultToolbarButtons(), getFlexFullToolbarButtons(), getFlexDefaultFloatingToolbars(), getFlexExtraTools(), getNativeComparisonToolbarButtons().
To override button layout, use Filament’s toolbarButtons() / floatingToolbars() / tools() with these presets — see Filament Rich Editor.
File attachments & images (package layer)
Requires FilamentfileAttachments() / disk options to be enabled first. This table lists Flex processing and cleanup on top of that baseline.
HTML rendering
Built-in plugins (automatic): block images (always), YouTube (when
youtube()), paste cleanup (when pasteCleanup()).
Shell variants
primary
secondary (default)
soft
flat
Shell sizes
sm
md (default)
lg
Focus outline
Word count
JSON debug badge
Content limits
Soft limits (default) — warn in footer, validate on save
Hard limits — block typing past max
editor.commands.undo() when the user exceeds max characters or words.
Min characters only
Max characters only
Max words only
Reading time
config('filament-flex-fields.rich_editor.reading_time_words_per_minute').
Fullscreen
Distraction-free
Hides clearFormatting and clearContent in the toolbar while fullscreen is active.Autosave
Saves editor JSON tolocalStorage. On reload, prompts to restore if a newer draft exists.
{statePath}::{model:id|create}::user:{id}.
Paste cleanup
YouTube embeds
Requires->youtube(). Adds toolbar button + TipTap extension + paste handler for YouTube URLs.
youtube.com/watch?v=, youtu.be/, youtube.com/embed/, youtube.com/shorts/.
Rendered HTML preserves data-youtube-video iframes through FlexRichContentRenderer::toHtml() sanitization.
Block images (automatic)
FlexRichEditorBlockImagePlugin is always registered. Images inserted in the editor are block-level (not inline with paragraph text). No configuration required.
Image overlay (editor only)
When file attachments are enabled, selecting an image shows Edit and Delete controls (top-right overlay). Not included in frontend HTML output.- Edit → opens Filament
attachFilesaction (alt text, replace). - Delete → removes image from document.
Toolbar presets
Default Flex toolbar (no attachFiles)
Full toolbar (with attachments button)
Custom toolbar
Native Filament comparison (playground)
Toolbar roles
Presets inconfig('filament-flex-fields.rich_editor.toolbar_roles').
Author
Editor
Admin
Custom role (after publishing config)
Disabled toolbar tools
flexFullscreen and plugin tools (youtube) use their tool names.
Floating toolbars
Default paragraph bubble (bold, italic, underline, strike, link). Hidden when an image is selected.Custom tools
Flex adds Gravity-icon tools viaFlexRichEditor::getFlexExtraTools():
clearFormatting— clear nodes + marksclearContent— empty document
fullscreen() is enabled, flexFullscreen tool is appended automatically.
File attachments
Uploads use Filament’s attachment API (fileAttachments(), disk, directory, visibility). Flex adds scoped paths, optimization, variants, and orphan cleanup on top.
Attachments are enabled when fileAttachments(true) or the toolbar includes attachFiles and Filament resolves hasFileAttachments().
Visibility
Scoped attachment directories
scopedAttachmentDirectory('rich-editor') resolves:
{prefix}/{model}/{id}/when editing a record{prefix}/drafts/{userId}/on create forms
Images only
Restricts accepted MIME types to images (JPEG, PNG, GIF, WebP).Max attachment size
Single-pass image optimization
Without named variants — resizes/optimizes the master file on upload.Named image variants
Generatesphoto__thumb.webp, photo__large.webp, and photo.jpg.flex-variants.json.
Array config
Fluent RichEditorImageVariant objects
max_long_edge, max_width, max_height, webp, master, optimize.
Automatic attachment cleanup
Native disk (default on)
.flex-variants.json manifests. Scoped directories also sweep unreferenced files.
Spatie Media Library
Disk pruner is skipped. Filament callsFileAttachmentProvider::cleanUpFileAttachments(exceptIds: [...]) on save.
Responsive images in HTML output
Lazy images on/off
Responsive srcset on/off
responsiveImages() defaults to on if not set explicitly.
Image sizes attribute
Rendering HTML
Always usemakeFlexRichContentRenderer() so disk, variants, plugins (YouTube), and lazy loading match the field.
From field instance (recommended)
In Filament infolist / table column
Standalone renderer
Example output
Blade view
Inertia / API controller
Alt text required
Accessibility
Built-in without extra configuration:Spatie Media Library (optional)
1. Model — register conversions
2. Form
3. Render
Complete example: Filament Resource
Configuration recipes
Minimal blog post
Production article (native disk)
Author role (limited toolbar)
Package config
config/filament-flex-fields.php:
Translations
Package strings:filament-flex-fields::default.rich_editor.* in resources/lang/en/default.php and resources/lang/pl/default.php.
Toolbar labels reuse Filament: filament-forms::components.rich_editor.tools.*.
Publish translations
Key reference
Testing
PHP (package)
JavaScript unit tests
Playwright E2E (playground)
Playground
/admin/flex-fields-playground/flex-rich-editor — see Playground.
Slug: flex-rich-editor
Includes:
- Native Filament
RichEditorcomparison - Full Article body demo (attachments, variants, limits, YouTube, fullscreen, autosave)
- Variant grid: compact / secondary / soft / flat
- Attachments-only and full-toolbar sections
Assets (CSS & JS)
Each field loads its own CSS bundle and Alpine component on demand (x-load). Optional support scripts load only when configured.
Does it duplicate Filament’s rich editor?
On a page with onlyFlexRichEditor: no double download of Filament’s rich-editor Alpine asset. The blade loads flex-rich-editor, not filament/forms → rich-editor.
JS bundle: at build time, flex-rich-editor.js bundles Filament’s rich-editor-form-component (esbuild alias to vendor/filament/forms/dist/components/rich-editor.js) plus Flex chrome (~500 KB raw — same order of magnitude as native Filament). That is a single runtime script, not Filament + Flex side by side.
CSS: Filament does not ship a separate rich-editor.css asset. Flex adds rich-editor-field.css for the fff-rich-editor-* shell and overrides on shared fi-fo-rich-editor-* markup classes. No second full editor stylesheet.
Exception — playground comparison: the Flex Rich Editor playground page may render native RichEditor next to FlexRichEditor for demo purposes. That page loads both rich-editor and flex-rich-editor scripts — intentional, not typical production usage.
Performance notes
- Footer stats use
requestAnimationFramebatching (not per-keystroke DOM thrashing). - Image overlay sync runs on selection changes only.
- Attachment manifest reads are cached per request during HTML rendering.
- Bundle budget (CI):
flex-rich-editor.js~497 KB raw / ~157 KB gzip (aligned with Filament native).
Requirements & optional packages
Filament RichEditor baseline
FlexRichEditor extends Filament\Forms\Components\RichEditor. Options not documented on this page behave as in Filament.
- Filament Rich Editor documentation
- JSON storage is enabled by default in
setUp()(json())