pathfindermediagroup/nova-froala-field
A Laravel Nova field that integrates the Froala WYSIWYG editor for rich text content. It provides an easy-to-use, configurable editing experience for creating and managing formatted HTML in Nova resources.
Install the package with Composer and let it publish its config and front-end assets:
composer require <vendor>/laravel-froala
php artisan vendor:publish --tag=froala-config
php artisan vendor:publish --tag=froala-assets
Look at these three places first, in this order:
config/froala.php — this is where the editor's default options (toolbar set, height, language, upload paths, license key) live. Almost every "how do I change X" question is answered here.resources/views/vendor/froala/ — the Blade partial/component that actually renders the <textarea> plus the init script. Read this before overriding anything, so you know which element IDs and JS variables the package depends on.public/vendor/froala/ — confirms which Froala build you're actually serving. This release (4.0.5) is purely an upstream bump to Froala 4.0.14, so the files here are the only thing that changed.Put your license key in .env (FROALA_LICENSE_KEY=...) and reference it from the config — the editor loads in "unlicensed" mode on a production domain otherwise.
The first real use case: a single editor in a Blade form. Render the package's component/partial against a content field, submit the form, store the HTML on your model, and render it back through a sanitizer. That end-to-end loop — edit → post → persist → display — is the one to get working before touching toolbars.
<form method="POST" action="{{ route('posts.store') }}">
@csrf
<x-froala name="content" :value="old('content', $post->content ?? '')" />
<button type="submit">Save</button>
</form>
Configuration profiles, not per-view JS. Rather than scattering new FroalaEditor(...) calls through Blade files, define named toolbar profiles in config/froala.php (e.g. minimal, full, comment) and pass a profile name from the component. This keeps every editor in the app consistent and makes a future Froala upgrade a one-file change.
Two-layer rendering. Store raw editor HTML, but always render it through a sanitizer (mews/purifier, HTMLPurifier, or a League HTML sanitizer with an explicit allowlist). Froala's HTML is browser-authored input; treat it as untrusted regardless of who the author is. Sanitize on save for the canonical copy and again on render for legacy rows.
Centralise the upload endpoint. Froala posts images/files to a URL you configure (imageUploadURL, fileUploadURL). Implement one controller that validates MIME + size, stores to a dedicated disk (public disk + php artisan storage:link, or S3), and returns the JSON shape Froala expects ({"link": "..."}). Doing this per-model gets messy fast — one endpoint with a policy check on the authenticated user is enough.
Wrap it in a Blade component. A thin <x-froala> that handles the unique ID, old() repopulation, wire:model bridging, and profile selection will pay for itself the second time you need an editor. The package's own partial is the reference implementation.
Livewire / Inertia. For Livewire, hook wire:ignore around the editor and re-initialise on Livewire.hook('morph.updated'); otherwise the DOM swap kills the editor instance. For Inertia, initialise in onMounted and destroy in onUnmounted to avoid leaking instances across visits.
Testing. Assert the textarea/component renders and that feature tests can POST HTML through your form and get sanitized output back. There's little value in asserting on the third-party JS in a browser-less test suite; push that into a Dusk test if you need it at all.
php artisan vendor:publish --tag=froala-assets --force) and hard-refresh, or you'll keep serving stale JS from public/vendor/froala/ and see no difference. Check the version string the editor reports against 4.0.14 to confirm the swap actually happened.php artisan config:clear && php artisan view:clear. A cached config referencing an old asset path is a classic "the upgrade did nothing" red herring.Content-Security-Policy, you'll need nonces or hashes, plus img-src/font-src for the editor's own assets.pasteAllowLocalImages/pasteDeniedTags (or the 4.x equivalents) rather than cleaning it up in the database later.plugins/scripts config array rather than editing the published vendor partial — your edits will be wiped by the next --force republish, which is exactly what this release asks you to do.Upgrade verdict: 4.0.5 is a low-risk patch. Bump the constraint, republish assets, clear caches, verify the 4.0.14 version string, and smoke-test image upload and paste. No integration code should need to change.
How can I help you explore Laravel packages today?