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

Laravel Ckeditor Laravel Package

jeroennoten/laravel-ckeditor

A Laravel package that integrates CKEditor into your application, offering Blade helpers and configuration to load the editor, manage assets, and customize toolbars. It simplifies adding rich-text editing to forms while keeping setup and options centralized in Laravel.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer and publish the config:

composer require jeroennoten/laravel-ckeditor
php artisan vendor:publish --provider="Jeroennoten\LaravelCkeditor\CkeditorServiceProvider"

On Laravel 5.5+ the provider/alias are usually auto-discovered; on older versions register Jeroennoten\LaravelCkeditor\CkeditorServiceProvider and the Ckeditor alias in config/app.php.

Look here first: config/ckeditor.php. It holds the CDN toggle, CKEditor version, language, default editor options, and the file-browser upload/browse route names. Almost every day-to-day tweak lives there or is passed as an options array per call.

First use case — replace a post body textarea in a form:

<textarea name="body" id="body">{{ old('body', $post->body ?? '') }}</textarea>

@push('scripts')
    {!! Ckeditor::script() !!}
    <script>{!! Ckeditor::replace('body') !!}</script>
@endpush

Render a textarea, include the script once in your layout's script stack, then initialise the editor by element id. That is the entire happy path.

Implementation Patterns

  • Keep the script tag in the layout, not the form. Push Ckeditor::script() into a @stack('scripts') in your base layout so it loads once per page, even when a form is included via a partial. Only Ckeditor::replace() belongs next to the textarea.
  • Config presets over ad-hoc arrays. Define named option sets (e.g. minimal, full) in config/ckeditor.php, then select one per form. This keeps toolbars and height settings out of Blade and consistent across admin screens.
  • Per-call overrides. Ckeditor::replace('body', ['height' => 400, 'removePlugins' => 'elementspath']) merges into the defaults — use this for the occasional one-off rather than editing config.
  • Reusable Blade partial/component. Wrap the <textarea> + Ckeditor::replace() in one partial that takes $name, $value, and $options, so every CRUD screen gets the same markup and init.
  • Multiple editors per page. Give each textarea a unique id and call replace() for each (or drive it from a data-editor attribute loop). Avoid re-initialising an id.
  • Uploads through your app. Point filebrowserUploadRoute / filebrowserBrowseRoute at your own routes, then return the expected CKEditor callback payload (CKEditorFuncNum, URL, message) or JSON for the modern integration. Protect those routes with auth and validation middleware as you would any upload endpoint.
  • Sanitise on save. CKEditor submits raw HTML. Run it through HTMLPurifier (mews/purifier or similar) before persisting, and treat stored HTML as untrusted on render.
  • Feature tests. In HTTP tests you only assert the textarea, the rendered Ckeditor::script() output, and the init snippet — CKEditor itself never boots in the test client, so test the form contract, not the editor.

Gotchas and Tips

  • This is a CKEditor 4 / Laravel 5-era package (last release Jan 2017). CKEditor 4 is end-of-life and no longer receives security updates; for a new build, prefer CKEditor 5 via npm or a maintained wrapper. Use this package when you are maintaining an existing Laravel 5/6–8 codebase.
  • Unescaped output matters. Ckeditor::script() and the replace snippet return HTML/JS; print with {!! !!}. Using {{ }} renders a broken page silently.
  • Config cache. After editing config/ckeditor.php, run php artisan config:cache again — stale config is the usual cause of "my toolbar change did nothing".
  • Double initialisation. Including Ckeditor::script() twice, or calling replace() on an id that already has an instance, throws a CKEditor "editor instance already exists" error. Guard with if (!CKEDITOR.instances[id]) when in doubt, and check duplicated layout stacks first.
  • CDN vs local assets. With cdn => true the editor silently fails without internet/CDN access. For offline or air-gapped installs, publish the assets and switch the config to local; verify the request in the network tab.
  • CSRF on uploads. The package injects the token for its file-browser config, but if you wire a custom upload endpoint double-check the header/field name matches your middleware, and that the route is not excluded from VerifyCsrfToken.
  • Language fallback. If the configured language has no matching CKEditor language file at the pinned version, it falls back to English with no visible error.
  • Pin the version string. The CDN URL is built from the config version; leaving it outdated drifts from the plugins you enable.
  • Debugging checklist: view page source to confirm the rendered config, inspect CKEDITOR.instances and CKEDITOR.config in the console, and watch the network tab for a failed ckeditor.js or config.js request.
  • Extension points: custom config.js via the config's custom-config option, extra plugins by adding files to the published plugins directory, and toolbar layout entirely through the options array — no need to fork the package.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin