wimski/nova-froala-field
A Laravel Nova field that integrates the Froala WYSIWYG editor for rich text editing. Easily add configurable Froala toolbars, image and file uploads, and HTML content editing to your Nova resources.
Install the field with Composer and let Laravel's package discovery register the service provider:
composer require wimski/nova-froala-field
If the package ships a config file, publish it next; otherwise the defaults are usually enough:
php artisan vendor:publish --provider="Wimski\NovaFroalaField\NovaFroalaFieldServiceProvider"
Where to look first:
Nova::script() / Nova::style() (or uses nova.mix) so the Froala JS/CSS bundle is loaded on the Nova dashboard.->options([...]), a dedicated config file, or fluent helpers like ->toolbar() / ->height().First use case — a basic rich-text body field in a Nova resource:
use Wimski\NovaFroalaField\Froala; // verify namespace in README
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Text::make('Title'),
Froala::make('Body'),
];
}
Run php artisan nova:publish if assets do not appear, then open a create/edit form and confirm the editor mounts. If the textarea renders as a plain input, the asset registration or component name is the issue — inspect the browser console first.
Customising the toolbar and height. Froala options are passed as a plain array and serialised to JS, so almost any valid Froala config key works:
Froala::make('Body')->options([
'toolbarButtons' => ['bold', 'italic', 'underline', '|', 'formatOL', 'formatUL', '|', 'insertLink'],
'toolbarButtonsXS' => ['bold', 'italic'],
'heightMin' => 300,
'placeholderText' => 'Write the article…',
'pluginsEnabled' => ['lists', 'link', 'codeView', 'fullscreen'],
]);
Keep option arrays small and serialisable — closures, resources, and objects will break the JSON payload.
Extracting a reusable field. Most projects standardise the toolbar once and reuse it. A small factory keeps resources consistent:
// app/Nova/Fields/ArticleBody.php
class ArticleBody extends Froala
{
public function __construct($name = 'Body')
{
parent::__construct($name);
$this->options([
'heightMin' => 300,
'toolbarButtons' => ['bold', 'italic', 'formatOL', 'formatUL', 'insertLink', 'codeView'],
]);
}
}
Image and file uploads. Froala uploads through imageUploadURL / fileUploadURL endpoints. Point these at a route in your app and protect it with the nova middleware and CSRF; return the JSON shape Froala expects ({"link": "..."}):
Froala::make('Body')->options([
'imageUploadURL' => '/nova-api/froala/upload',
'imageUploadParams' => ['_token' => csrf_token()],
]);
Store uploads through Laravel's filesystem on a disk your field/renderer can read from, and validate MIME type and size server-side — Froala does not validate on the server for you.
Display vs. edit. On detail and index views, HTML is rendered rather than the editor. Decide early whether to strip tags:
Froala::make('Body')
->hideFromIndex()
->displayUsing(fn ($value) => Str::limit(strip_tags($value), 120));
Integration with other Nova features. Standard field modifiers compose normally — ->rules('required'), ->nullable(), ->dependsOn(), ->readonly(), ->help(). Because the value is HTML, ->rules('max:65535') matters for TEXT columns, and sanitisation belongs in a FormRequest or mutator rather than the field.
froalaEditor.key option or a licensed build). This is the single biggest reason teams pick TinyMCE/Quill instead. Check the package's Froala version before assuming a license key is wired in.{!! $model->body !!} without sanitising — use HTMLPurifier, mews/purifier, or a strict allow-list. Consider storing sanitised HTML at write time.Nova::script()/Nova::style() registration and that php artisan nova:publish has run. Nova 4+ caches compiled assets; clear with php artisan nova:publish --force and hard-refresh.->options() replaces defaults or merges into them. If it replaces, omitting keys like toolbarButtons can leave you with the full default toolbar unexpectedly — or no toolbar at all.imageUploadURL bypasses Nova auth and CSRF. Register the route inside your app with the nova middleware group and validate with a FormRequest._token via imageUploadParams/fileUploadParams or Laravel will 419.style-src 'unsafe-inline' and appropriate img-src allowances. Debug in the browser console — CSP violations appear there, not in Laravel logs.attribute and that the column is TEXT/LONGTEXT.language in options and ensure the language file is served, otherwise the editor silently falls back to English.How can I help you explore Laravel packages today?