blari18570/livewire-summernote
Laravel Livewire wrapper for the Summernote WYSIWYG editor. Drop a Summernote component into your Livewire forms, bind content with wire:model, and handle updates/events for rich-text editing in your app.
Installation
composer require blari18570/livewire-summernote
Publish the config (if needed):
php artisan vendor:publish --provider="Blari18570\LivewireSummernote\LivewireSummernoteServiceProvider"
Basic Usage Add the component to a Livewire class:
use Blari18570\LivewireSummernote\LivewireSummernote;
public $content = '';
public function mount()
{
$this->content = '<p>Initial content</p>';
}
public function render()
{
return view('livewire.your-component', [
'summernote' => LivewireSummernote::make('content')
->height(300)
->toolbar([
['groupName' => 'style', 'buttons' => ['bold', 'italic']],
]),
]);
}
Blade Integration
@livewire('your-component')
Replace a standard <textarea> with a rich-text editor in a form:
// Livewire component
public $description = '';
public function updatedDescription()
{
// Auto-save or validate content
}
<div>
{{ $summernote }}
</div>
Dynamic Toolbar Configuration
LivewireSummernote::make('content')
->toolbar([
['groupName' => 'paragraph', 'buttons' => ['paragraph', 'blockquote']],
['groupName' => 'insert', 'buttons' => ['link', 'picture']],
]);
Image Upload Handling
Use the imageUpload callback to process uploaded files:
LivewireSummernote::make('content')
->imageUpload(function ($file) {
$path = $file->store('summernote-images');
return asset("storage/{$path}");
});
Validation Integration
use Illuminate\Validation\Rule;
public function rules()
{
return [
'content' => ['required', Rule::unique('posts')->ignore($this->post->id)],
];
}
Reusable Components Create a base component for forms:
// SummernoteFormComponent.php
public function mount($model, $field)
{
$this->field = $field;
$this->model = $model;
}
public function render()
{
return view('livewire.summernote-form', [
'summernote' => LivewireSummernote::make($this->field)
->height(400)
->toolbar($this->getToolbar()),
]);
}
Live Updates Sync content across components:
public $sharedContent;
public function updatedContent()
{
$this->sharedContent = $this->content;
}
// resources/js/app.js
import 'summernote/dist/summernote-lite.min.css';
import 'summernote/dist/summernote-lite.min.js';
<div class="summernote-container p-4 bg-gray-50 rounded-lg">
{{ $summernote }}
</div>
wire:model directive for reactivity:
{{ $summernote->wireModel('content') }}
Double Initialization
wire:ignore on the container:
<div wire:ignore>
{{ $summernote }}
</div>
CSRF Token Conflicts
@csrf:
<form method="POST" enctype="multipart/form-data">
@csrf
<!-- form fields -->
</form>
Toolbar Button Misalignment
buttonList option for precise control:
->toolbar([
['groupName' => 'custom', 'buttons' => ['customButton']],
])
->buttonList([
'customButton' => {
'text': 'Custom',
'callback': function() { /* logic */ }
}
]);
Uncaught TypeError in browser console. Often caused by missing dependencies or incorrect initialization.telescope:record to log requests:
public function imageUpload($file)
{
\Illuminate\Support\Facades\Telescope::record(
new \Illuminate\Support\Facades\Telescope\Entries\IncomingRequest($file->toArray())
);
// ... rest of the logic
}
Default Height
config/livewire-summernote.php:
'default_height' => 500,
Language Support
LivewireSummernote::make('content')
->lang('es-ES') // Spanish
->initCallback("summernote.lang = 'es-ES';");
Lazy Loading
LivewireSummernote::make('content')
->initCallback("setTimeout(function() { $('#summernote').summernote(); }, 1000);");
Custom Plugins Extend Summernote with plugins:
LivewireSummernote::make('content')
->plugins(['summernote-plugin-name'])
->initCallback("$('#summernote').summernote('codeview.show');");
Event Listeners Hook into Summernote events:
LivewireSummernote::make('content')
->initCallback("
$('#summernote').on('summernote.change', function(we, contents) {
Livewire.emit('contentChanged', contents);
});
");
Alpine.js Integration Combine with Alpine for dynamic updates:
<div x-data="{ isEditing: false }">
@if($isEditing)
{{ $summernote->wireModel('content') }}
@else
<div x-text="$wire.content"></div>
@endif
</div>
How can I help you explore Laravel packages today?