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

Redactor Bundle Laravel Package

kraksoft/redactor-bundle

Symfony bundle for integrating the Imperavi Redactor WYSIWYG editor, with configuration and form support for adding rich-text editing fields to your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check before you type composer require. This package is a Symfony2 bundle, not a Laravel package. There is no service provider, no facade, no config/redactor.php to publish, and no bundle-registration hook in Laravel's bootstrap/providers.php. Running the install will either fail on constraints or drag legacy Symfony 2 components into a Laravel 10/11 tree and break autoloading. Confirm the constraint in the repo's composer.json (symfony/symfony ~2.x, PHP 5.x era) before wasting time.

# Do NOT run this in a modern Laravel app — expect constraint conflicts
composer require kraksoft/redactor-bundle

Where to look first, as a Laravel developer. Treat the repo as reference documentation, not a dependency. Two files are worth reading:

  1. The DI extension / configuration tree — shows which Redactor options the author exposed (toolbar, buttons, language). This tells you the shape of a config file you'd build yourself.
  2. The form type (AbstractType + Twig form theme) — shows how the editor mounts on a textarea. This is the part you'll reimplement as a Blade component.

Your first real use case. A Laravel developer's realistic first task is not "install and use this." It is: "I need a rich-text field on a form." Do this instead:

# Pick a maintained, framework-agnostic editor
npm install @tiptap/core @tiptap/starter-kit
# or tinymce, quill, ckeditor5, lexical

If a stakeholder insists on Redactor specifically, that's a procurement + asset-vendoring task (see below), not a Composer task. Either way, the day-to-day work is a Blade component plus a Vite bundle — nothing from this repo is importable.

Implementation Patterns

Pattern 1 — Port the concept, not the code. The bundle's one transferable idea is: "one reusable form control that renders a textarea, mounts the editor client-side, and returns HTML." Reproduce that as a Blade component.

{{-- resources/views/components/rich-text.blade.php --}}
@props(['name', 'value' => '', 'options' => []])

<textarea name="{{ $name }}" {{ $attributes }}>{{ $value }}</textarea>

@push('scripts')
<script>
  document.addEventListener('DOMContentLoaded', () => {
    // editor init — Redactor, Tiptap, whatever you vendored
    window.initRichText(document.querySelector('[name="{{ $name }}"]'), @json($options));
  });
</script>
@endpush

Use it as <x-rich-text name="body" :value="$post->body" /> inside any Blade form.

Pattern 2 — Asset delivery via Vite, not web/. The bundle assumes Symfony's assets:install copies files into web/. In Laravel your assets live in resources/ and build into public/build/ through Vite. Vendor the editor package there:

// resources/js/app.js
import './vendor/redactor/redactor.min.js'; // per Imperavi license
import './rich-text';

Never point a <script src="/bundles/kraksoftredactor/..."> at public/ — it won't exist.

Pattern 3 — Config as a published PHP array. Mirror the bundle's config tree in config/rich-text.php, then read it in the component:

// config/rich-text.php
return [
    'buttons'  => ['html', 'format', 'bold', 'italic', 'link', 'lists'],
    'lang'     => 'en',
    'min_height' => 200,
];

This is the equivalent of the Symfony DI extension — you own it, it's versionable, and it doesn't require a bundle.

Pattern 4 — Sanitize on save and render. This is the pattern the bundle deliberately omits. Build it once:

use Mews\Purifier\Facades\Purifier;

$post->body = Purifier::clean($request->input('body')); // save
// and cache the cleaned output rather than re-running on every render

If you follow the bundle's own conventions too literally, you'll store raw editor HTML and render it unescaped — that's a stored-XSS pattern, not a feature.

Pattern 5 — Uploads are your endpoint. The bundle provides none. If the editor needs inline images, own the controller behind auth + a policy + MIME/size validation:

Route::post('/rich-text/upload', [RichTextUploadController::class, 'store'])
    ->middleware(['auth', 'throttle:uploads']);

Pattern 6 — If you inherit a Symfony 2 app. Don't add the package as a fresh dependency — vendor the ~200 lines of glue into src/ (form type + Twig theme + config), pin the commit, and treat it as frozen. You're now the maintainer, which you would be anyway, but at least composer update won't take the app down.

Gotchas and Tips

  • Composer will fight you. symfony/symfony ~2.x and PHP 5.x constraints hard-conflict with any modern Laravel install. If you see "your requirements could not be resolved," do not try to --ignore-platform-reqs your way through — you'll end up with Symfony 2 components loaded alongside Laravel and mysterious Class not found errors at boot.

  • There is no Laravel registration path. AppKernel::registerBundles() has no analog. If a guide tells you to add the bundle to config/app.php providers, that guide is for a different package — stop following it.

  • The editor is not included. Redactor is commercially licensed by Imperavi, per seat/domain. The bundle's name implies it ships the editor, but you must obtain and vendor the JS yourself. Budget this as a procurement decision, not a composer require.

  • assets:install targets web/, not public/build/. Even if you port code, the asset path assumptions are Symfony-flavored. Route everything through Vite and delete the bundle's asset commands from your mental model.

  • jQuery-era assumptions. Older Redactor versions expect a global jQuery and manipulate the DOM in ways that collide with Alpine, Livewire morphs, and Stimulus. If any of those are in the page, test the editor's lifecycle carefully — re-mounting after a Livewire update is a common failure.

  • CSP is a silent killer. Legacy Redactor initializes with inline scripts and often eval-adjacent code paths. A strict Content-Security-Policy (no unsafe-inline/unsafe-eval) will make the editor fail to mount with no error in the UI — check the browser console first when "the box is empty."

  • No sanitization, no upload validation, no media library. The bundle provides the mounting glue and nothing else. Treat stored-HTML XSS as the highest-severity risk of a naive port and make Purifier or HTMLPurifier a day-one dependency, not a follow-up ticket.

  • Store portable HTML, not editor JSON. If you later swap editors (and for a package this abandoned, you almost certainly will), semantic HTML in the body column makes the swap a render-layer change. Editor-specific JSON blobs make it a data migration.

  • Extension points are Symfony-specific. Overriding defaults here means the DI config tree and Twig form theme — both meaningless in Laravel. Your "extension points" in a Laravel port are the published config/rich-text.php array and the Blade component's $options prop. Design them for overrides from the start so you don't rebuild later.

  • Debugging checklist when the editor doesn't appear:

    1. Browser console — CSP or JS load errors.
    2. Network tab — is the editor.js actually served from public/build?
    3. Is there a duplicate jQuery or a DOMContentLoaded that fired before the component mounted?
    4. If content saved correctly but doesn't render, you're stripping it on output — check {!! !!} vs {{ }} balance against your sanitizer.
  • The 3-star / 0-dependent situation is the real tip. There is no community to surface regressions, no security advisories, and no PHP 8.3/8.4 fixes coming. Every failure mode above lands on you. The cheapest day-to-day leverage is to not depend on this package at all — study its config shape for five minutes, then build a small Blade component around a maintained editor and move on.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource