rawilk/filament-quill
A Filament form field that brings the Quill rich text editor to your admin panels, with configurable toolbars and easy content handling.
Install the package via Composer and let Filament pick up its assets:
composer require rawilk/filament-quill
php artisan filament:assets # if you publish/serve assets explicitly
There is usually no mandatory config publish; if you need to tweak defaults, publish the package config/views and inspect the options there first:
php artisan vendor:publish --tag="filament-quill-config"
The fastest first use case is replacing a RichEditor on a content field:
use Rawilk\FilamentQuill\Forms\Components\QuillEditor;
QuillEditor::make('content')
->toolbarButtons(['bold', 'italic', 'link', 'bulletList', 'orderedList', 'blockquote'])
->minHeight('12rem');
Look first at the field class itself (methods for toolbar buttons, min height, and Quill options) and at the published config for anything you'd otherwise set globally. For day-to-day work, treat QuillEditor as a drop-in form component: add it to a Form, persist the HTML string like any other text column, and render it back through your normal (sanitized) output path.
Form fields. Use QuillEditor::make('column') inside form() schemas like any other Filament field. Chain toolbar/min-height configuration per field rather than globally when different resources need different editing surfaces:
QuillEditor::make('body')
->toolbarButtons(['bold', 'italic', 'link'])
->minHeight('8rem')
->columnSpanFull();
Global defaults. For consistent toolbars across a panel, set defaults once in the published config and only override on the exceptional fields. This keeps resource classes short and reduces drift between forms.
Persisting and rendering. The field stores HTML. Keep a single sanitization path on the server (e.g. an HTML purifier or a trusted-markdown-to-HTML pipeline) applied on save and/or on render, and never echo raw editor output with {!! !!} unless it has been sanitized. A common pattern is ->dehydrateStateUsing(fn ($state) => $this->sanitize($state)) on the field, or sanitizing in the model/observer.
Tables and previews. Since content is HTML, use TextColumn::make('body')->html()->limit(...) or strip tags for list views; don't let full Quill markup leak into table cells.
Custom Quill behaviour. For anything beyond toolbar buttons, pass additional Quill options through the field/config (or a small custom Alpine/JS hook) rather than forking the package. Keep custom modules registered in a panel asset so they load wherever the field is used.
Testing. Feature tests can set the field the same way as other Filament fields (fillForm(['content' => '<p>Hello</p>'])); assert on stored HTML rather than on editor DOM. If you assert sanitized output, test both the save and render paths.
<br> versus <p> patterns, and your sanitizer/CSS must handle both. This is a patch-level behaviour change, so verify rendering after upgrading.@apply to direct CSS. If you were overriding the editor height via @apply in a custom theme or panel stylesheet, switch to plain CSS or the field's minHeight() option; the direct-CSS approach is more reliable when Tailwind isn't compiled in the panel, but any custom @apply-based override will no longer match.php artisan optimize:clear, and re-run filament:assets if you publish them) or you can end up serving the old editor JS/CSS and see stale behaviour.composer.json constraint for the Filament major you run before upgrading; keep the editor package version aligned with the panel version rather than mixing majors.live() validation, expect validation to fire on blur rather than per keystroke. Add debounce or rely on submit-time validation if that's disruptive.How can I help you explore Laravel packages today?