Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Froala Editor Bundle Laravel Package

kms/froala-editor-bundle

A Laravel bundle that integrates the Froala WYSIWYG editor into your application, providing a ready-made rich text editing field with its assets, configuration, and framework-friendly setup for quickly adding Froala to forms and content management screens.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: this is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config publish tag. In a Laravel app you will not install this — you install froala-editor from npm and replicate the ~80 lines of glue this bundle provides. The value of reading it is that it shows you the canonical wiring (options merging, per-profile config, form integration, upload endpoints) so you can copy the shape into a Blade component + a small FroalaOptions service.

For a Symfony app, the minimal path:

composer require kms/froala-editor-bundle

Register KMS\FroalaEditorBundle\KMSFroalaEditorBundle in config/bundles.php (Flex does this for you), then the smallest useful config:

# config/packages/kms_froala_editor.yaml
kms_froala_editor:
    language: en
    height: 300
    toolbar: [bold, italic, underline, "|", insertLink, insertImage, "|", html]

Use it as a form field — this is the 90% use case:

use KMS\FroalaEditorBundle\Form\Type\FroalaEditorType;

$builder->add('body', FroalaEditorType::class);

Or standalone in Twig against your own <textarea id="body">:

{{ froala_editor() }}

Where to look first, in this order:

  1. README.md — thin, but has the config sample and the form/Twig examples.
  2. DependencyInjection/Configuration.php — the authoritative list of every YAML key. This is the real documentation.
  3. Service/OptionManager.php — how YAML keys become the JS options object, including defaults you didn't ask for.
  4. Form/Type/FroalaEditorType.php — the form-level options (profile, froala_options, attr).

First use case to prove it works: an Article form with a body field, save the HTML, render it back with |raw after sanitizing. If that round-trips without the toolbar disappearing or the content being HTML-escaped twice, the integration is sound.

Implementation Patterns

Named profiles instead of per-field option arrays. Define the two or three editor shapes you actually need once in YAML, then reference them. This keeps options out of PHP and makes them editable without a deploy review of form classes.

kms_froala_editor:
    profiles:
        default:
            height: 300
            toolbar: [bold, italic, insertLink]
        full:
            height: 500
            toolbar: [bold, italic, underline, insertTable, insertImage, html]
            imageUploadURL: /admin/upload/image
$builder->add('body', FroalaEditorType::class, ['profile' => 'full']);

Configurator service for anything dynamic. The bundle's real extension point is ConfiguratorInterface: a service that receives the resolved options before render, so you can vary the toolbar by role, inject a signed upload URL, or flip toolbarInline for a specific entity. Wire it via the configurator config key. Use this rather than sprinkling froala_options arrays across form types — one place to reason about, one place to test.

Upload endpoints are yours to write, and they are the security boundary. Froala POSTs the file and expects {"link": "https://..."} back. In Symfony that's a controller taking Request $request and UploadedFile; in Laravel an invokable controller with a FormRequest. Non-negotiables: validate by extension and re-encode images, generate random filenames, store outside the public root or in a dedicated disk, and return only the public URL. Do not pass the user's filename through. Bind the endpoint behind your admin middleware — an open imageUploadURL is an unauthenticated file-upload primitive.

Sanitize on write, not on read. Store clean HTML in the column. Use HTMLPurifier (ezyang/htmlpurifier, or mews/purifier in Laravel) with a whitelist covering only the tags your toolbar can produce. Then {{ article.body|raw }} (Twig) / {!! $article->body !!} (Blade) is a defensible render. If you skip this, one paste from Word carries <style> blocks and onerror attributes straight into your database.

Multiple editors / dynamic forms. Each rendered textarea needs its own new FroalaEditor('#id', opts) call. For Symfony collection types or Alpine/Livewire-driven "add another block" UIs, the initializer runs once on DOM ready — you must re-init manually after inserting nodes. Keep a per-page registry of instances and destroy them on removal; otherwise you accumulate orphaned toolbars.

Laravel translation of the pattern: npm i froala-editor, import CSS/JS in resources/js/app.js, build a <x-froala name="body" profile="full" /> Blade component that renders a textarea plus an inline new FroalaEditor call sourced from a config/froala.php array shaped identically to the bundle's YAML. Same mental model, none of the bundle.

Gotchas and Tips

  • Froala is commercially licensed. The bundle ships no assets and no key. Development is free; production needs a key passed through the options array. Budget for this before you build a CMS on it.
  • The CDN option pins a specific Froala version. If useCDN is on, the bundle loads whatever version its asset URL references. Mixing that with locally installed plugins from a different Froala major is the classic "plugin silently does nothing" bug. Pick one source of truth for assets.
  • YAML eats your toolbar separators. "|" must be quoted or YAML treats it as a block scalar and your toolbar becomes one giant string. Same for any option expecting a literal pipe.
  • debug:config is your friend. Config is compiled; after editing YAML run bin/console cache:clear and bin/console debug:config kms_froala_editor to see the merged result rather than guessing why an option had no effect. Then inspect the inline <script> in the rendered page — that is the actual options object Froala received.
  • Content sync on non-standard submits. Froala mirrors into a hidden textarea on native form submit. AJAX submits, Livewire round-trips, and fetch() posts bypass that. Call the editor's HTML getter explicitly before sending.
  • Turbo/Turbolinks/Inertia navigation leaves editors behind. Destroy instances on turbo:before-cache (or your router's equivalent) or you get flickering duplicated toolbars and leaked listeners.
  • Pasting is the main source of junk markup. Set the paste/enter behavior explicitly (enter, paste-as-text where appropriate) rather than relying on defaults, and keep the sanitizer whitelist in sync with the toolbar you expose.
  • CSRF on upload routes. The upload POST needs your token. Pass it via the editor's upload params and validate normally — a 419 on image upload is a five-minute confusion for every new developer.
  • Low bus factor. One star, zero dependents in the dataset, last release mid-2024. Pin the exact version in composer.json, assume you may need to fork it, and don't build your editor abstraction so tightly around its form type that swapping to a hand-rolled Twig include is painful. The abstraction you actually want is "my options array + my upload endpoint," and both are portable.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment