Weave Code
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

Ckeditor5 Livewire Laravel Package

mati365/ckeditor5-livewire

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require mati365/ckeditor5-livewire
    npm install --save-dev @ckeditor/ckeditor5-build-classic
    

    Publish assets (if needed):

    php artisan vendor:publish --provider="Mati365\Ckeditor5Livewire\Ckeditor5LivewireServiceProvider" --tag=public
    
  2. Basic Livewire Component Usage

    use Mati365\Ckeditor5Livewire\Ckeditor5Livewire;
    
    public $content = '<p>Hello World!</p>';
    
    public function mount()
    {
        $this->content = '<p>Default content</p>';
    }
    
    public function render()
    {
        return view('livewire.example', [
            'editor' => Ckeditor5Livewire::make('content')
                ->config([
                    'language' => 'en',
                    'toolbar' => ['heading', '|', 'bold', 'italic', 'bulletedList']
                ])
        ]);
    }
    
  3. Blade Form Integration

    <form wire:submit.prevent="save">
        {!! $editor !!}
        <button type="submit">Save</button>
    </form>
    

First Use Case

Replace a <textarea> with a rich editor in a Livewire form for blog posts or CMS content. The package handles real-time updates via Livewire’s reactivity.


Implementation Patterns

Core Workflows

  1. Dynamic Editor Configuration Use config() to customize editor behavior per component:

    Ckeditor5Livewire::make('content')
        ->config([
            'language' => $this->user->locale,
            'plugins' => ['Image', 'Table'],
            'image' => [
                'upload' => [
                    'types' => ['jpeg', 'png'],
                    'url' => route('upload.image')
                ]
            ]
        ]);
    
  2. Reusable Editor Components Create a base component for shared configurations:

    // BaseEditor.php
    class BaseEditor extends Component
    {
        public function getEditor()
        {
            return Ckeditor5Livewire::make('content')
                ->config(config('ckeditor.default_config'))
                ->allowedFileExtensions(['jpg', 'png', 'pdf']);
        }
    }
    
  3. Handling File Uploads Pair with a Livewire upload handler:

    // UploadHandler.php
    public function uploadImage()
    {
        $this->validate(['upload' => 'required|image']);
        $path = $this->upload->store('uploads');
        return ['url' => asset($path)];
    }
    
  4. Localization Load translations dynamically:

    Ckeditor5Livewire::make('content')
        ->config([
            'language' => app()->getLocale(),
            'languageForContent' => app()->getLocale()
        ]);
    

Integration Tips

  • Asset Optimization: Use Laravel Mix/Vite to bundle CKEditor with your app’s JS.
  • Livewire Hooks: Extend editor behavior with wire:ignore for non-Livewire JS:
    <div wire:ignore>
        <script>
            document.addEventListener('livewire:init', () => {
                Livewire.hook('editor.ready', (editor) => {
                    editor.ui.getEditableElement().parentElement.style.border = '1px solid #ccc';
                });
            });
        </script>
    </div>
    
  • Validation: Sanitize HTML output with Illuminate\Support\Str::of($this->content)->markdown() or a package like spatie/laravel-html-sanitizer.

Gotchas and Tips

Pitfalls

  1. Asset Loading Conflicts

    • Issue: CKEditor fails to load if multiple versions are included.
    • Fix: Ensure @ckeditor/ckeditor5-build-classic is installed only once (check node_modules and vendor).
    • Debug: Clear npm cache (npm cache clean --force) and rebuild assets.
  2. Livewire Reactivity Delays

    • Issue: Editor content doesn’t update immediately after Livewire state changes.
    • Fix: Use wire:model.live or trigger a manual update:
      Livewire.hook('editor.contentUpdated', (editor) => {
          editor.model.document.getRoot().getChild(0).setHtml(editor.data);
      });
      
  3. CSRF Token Mismatch

    • Issue: File uploads fail with 419 errors.
    • Fix: Ensure Livewire’s CSRF meta tag is present in the layout:
      @livewireScripts
      @stack('scripts')
      
  4. Custom Builds Not Loading

    • Issue: Custom CKEditor builds (e.g., @ckeditor/ckeditor5-build-balloon) fail silently.
    • Fix: Explicitly set the build path in config:
      'build_path' => public_path('vendor/ckeditor5-custom-build/build.js'),
      

Debugging

  • Check Editor Initialization: Open browser dev tools (Console tab) and verify CKEditor logs no errors. Look for:
    console.log('CKEditor initialized:', window.CKEDITOR);
    
  • Livewire Logs: Enable Livewire debugging:
    Livewire::configureLogging(function () {
        return [
            'driver' => 'single',
            'path' => storage_path('logs/livewire.log'),
            'level' => 'debug',
        ];
    });
    

Extension Points

  1. Custom Plugins Add plugins via config():

    ->config([
        'plugins' => ['MyCustomPlugin'],
        'extraPlugins' => ['myplugin']
    ]);
    

    Register the plugin in your JS:

    import MyCustomPlugin from './MyCustomPlugin';
    ClassicEditor.create(document.querySelector('#editor'), {
        extraPlugins: [MyCustomPlugin]
    });
    
  2. Event Listeners Hook into editor events via Livewire’s JS hooks:

    Livewire.hook('editor.ready', (editor) => {
        editor.model.document.on('change:data', () => {
            editor.data = editor.model.document.getData();
        });
    });
    
  3. Server-Side Processing Use Livewire’s updated* methods to process HTML:

    public function updatedContent($value)
    {
        $this->content = Str::of($value)->replaceMatches('/<img[^>]+src="([^"]+)"/', function ($match) {
            return '<img src="' . asset('storage/' . ltrim($match[1], '/')) . '">';
        });
    }
    

Configuration Quirks

  • Default Config: Override globally in config/ckeditor.php:
    'default_config' => [
        'removePlugins' => ['ImageUpload'], // Disable by default
        'toolbar' => ['heading', '|', 'bold', 'italic']
    ],
    
  • Dynamic Configs: Merge configs dynamically:
    $config = array_merge(
        config('ckeditor.default_config'),
        ['language' => $this->user->locale]
    );
    Ckeditor5Livewire::make('content')->config($config);
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope