ek0519/quilljs
ek0519/quilljs is a Laravel package that integrates the Quill.js WYSIWYG editor, making it easy to add rich text editing to forms and Blade views. It offers a straightforward setup for configurable JavaScript-based content editing in Laravel applications.
Install via Composer and let Nova auto-discover the field:
composer require ek0519/quilljs
There is no publish step in the typical case—the field registers itself through Nova's field service provider discovery. Look first at the package's src/ directory for the Quilljs field class and the resources/js/ bundle to confirm which Quill version and Vue component are shipped; with only 26 stars and no dependents, verify the repo is still compatible with your Nova major version before committing.
First use case—drop it into a Nova resource exactly like a Text field:
use Ek0519\Quilljs\Quilljs;
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Text::make('Title'),
Quilljs::make('Body'),
];
}
Render it on the detail view and confirm the toolbar appears and HTML persists to your body column. If the editor loads but content does not save, you most likely need a cast or a mutator (see Gotchas) rather than a config change.
Basic field with sensible defaults. The simplest integration is a single Quilljs::make('Body'). The field stores the editor output as an HTML string, so pair it with a text/longText column and treat the value as trusted HTML only if you sanitize on render.
Configuring the toolbar. Most day-to-day customization is toolbar/module configuration passed through the field's fluent options (the package forwards options to Quill). Typical pattern:
Quilljs::make('Body')
->withFiles('public') // if file/image handling is wired
->options([
'theme' => 'snow',
'placeholder' => 'Write the article…',
'modules' => [
'toolbar' => [
['bold', 'italic', 'underline', 'strike'],
['link', 'blockquote', 'code-block'],
[{ list: 'ordered' }, { list: 'bullet' }],
['clean'],
],
],
]);
Check the field class for the exact method name (options() vs config() vs withToolbar()) in the version you install—this package's API has shifted between releases.
Using it on the index/detail views. Quill output is HTML; Nova's index view will show raw markup unless you truncate/sanitize. Common pattern:
Quilljs::make('Body')
->hideFromIndex()
->rules('required', 'max:65000');
Or keep it on the index but strip tags via an accessor on the model.
Pairing with a preview field. Because Quill round-trips HTML that may include inline styles, a clean approach is to keep the raw editor value in one column and expose a sanitized rendered_body accessor for the front end, leaving Nova to edit the source of truth.
Form validation and sanitization. Combine Nova rules with a sanitizer (e.g. HTMLPurifier or mews/purifier) in a saving observer or model mutator so stored HTML is safe to echo with {!! !!} later.
Integration with other Nova packages. It composes like a normal field—place it inside Flexible::make(...), Panel layouts, or conditional fields (->dependsOn(...)). Because it is a client-side Vue component, it inherits Nova's reactivity, so ->readonly()/->disabled() and dependsOn work as expected.
ek0519/quilljs) means this is effectively unmaintained relative to nova-quill or laravel-nova-quill. Pin the version and audit the JS bundle before production; be prepared to fork.{!! $model->body !!} with content authored by lower-trust users.array/json, the editor will show serialized noise. Store as plain text/longText and cast nothing.modules.toolbar) and that you have not nested it under an options.options key.withFiles(), prefer it; otherwise add a custom image handler uploading to Nova's storage—don't assume uploads are wired out of the box.<quilljs-field>) usually means the field's script failed to register, often a Nova asset/manifest issue after upgrade. php artisan nova:publish and a hard refresh fix many of these.max rule counts characters of HTML including tags, so a 65,000-byte TEXT column can overflow from a relatively short article. Validate against your actual column type or use longText.node_modules/vendor, which will be lost on composer update.How can I help you explore Laravel packages today?