awcodes/filament-tiptap-editor
A TipTap-powered rich text editor for Filament. Adds a configurable WYSIWYG field with modern editing tools like formatting, links, lists, headings, code blocks, and more. Built to integrate cleanly with Filament forms and resources.
Installation
composer require awcodes/filament-tiptap-editor
Publish the config (optional):
php artisan vendor:publish --provider="Awcodes\FilamentTiptapEditor\FilamentTiptapEditorServiceProvider" --tag="config"
Basic Usage Register the editor in a Filament form:
use Awcodes\FilamentTiptapEditor\Forms\Components\TiptapEditor;
TiptapEditor::make('content')
->required()
->columnSpanFull(),
First Use Case
Replace a standard Textarea or RichEditor with a more powerful WYSIWYG editor in a Filament resource:
public static function form(Form $form): Form
{
return $form
->schema([
TiptapEditor::make('bio')
->label('Biography')
->rows(5),
]);
}
Customizing Toolbar
Extend the default toolbar via config (config/filament-tiptap-editor.php):
'toolbar' => [
'group1' => ['bold', 'italic', 'underline'],
'group2' => ['bulletList', 'orderedList', 'blockquote'],
// Add/remove buttons as needed
],
Or dynamically in code:
TiptapEditor::make('content')
->toolbar([
['bold', 'italic'],
['heading', '|', 'bulletList'],
]),
Handling Content
->html() to retrieve it:
$record->content; // Returns stored HTML
Str::of() or a package like spatie/laravel-html to sanitize before saving:
$cleanHtml = Str::of($request->content)->sanitizeHtml();
Integration with Filament Tables
Display formatted content in tables using ->toggleable() or custom render:
use Awcodes\FilamentTiptapEditor\Tables\Columns\TiptapEditorColumn;
TiptapEditorColumn::make('content')
->toggleable(isToggledHiddenByDefault: false),
Multi-Language Support Configure language packs via config:
'lang' => 'es', // Spanish (default: 'en')
Or per field:
TiptapEditor::make('description')
->lang('fr'), // French
Validation Combine with Filament’s validation rules:
TiptapEditor::make('terms')
->required()
->maxLength(5000),
Dynamic Toolbar Based on User Role
Override the toolbar in a Form modifier:
public function form(Form $form): Form
{
return $form
->schema([
TiptapEditor::make('content')
->toolbar(auth()->user()->isAdmin() ? $adminToolbar : $defaultToolbar),
]);
}
Custom Extensions Register Tiptap extensions via config or service provider:
// config/filament-tiptap-editor.php
'extensions' => [
'StarterKit',
'Tables',
'CodeBlock',
],
Or add custom extensions:
TiptapEditor::make('content')
->extensions([
new \Awcodes\FilamentTiptapEditor\Extensions\CustomExtension(),
]),
Live Preview
Use the ->livewire() method to enable real-time updates:
TiptapEditor::make('preview_content')
->livewire(),
Fallback for Non-JS Users Provide a fallback textarea:
TiptapEditor::make('fallback_content')
->fallbackTextarea(),
HTML Injection Risks
$record->update(['content' => Str::of($request->content)->sanitizeHtml()]);
spatie/laravel-html for stricter sanitization:
composer require spatie/laravel-html
use Spatie\Html\HtmlFacade;
$cleanHtml = HtmlFacade::sanitize($rawHtml);
Toolbar Button Misalignment
|:
->toolbar([
['bold', 'italic', '|', 'underline'],
['bulletList', 'orderedList'],
]),
Performance with Large Content
->rows(10) to constrain initial textarea size.Conflicts with Other Filament Plugins
filament-spatie-laravel-medialibrary.->script() to defer:
->script(<<<'JS'
document.addEventListener('DOMContentLoaded', function() {
initTiptapEditor();
});
JS)
Database Storage Size
->columnType('longText') or adjust your DB column:
Schema::table('posts', function (Blueprint $table) {
$table->longText('content')->change();
});
Console Errors
'debug' => env('APP_DEBUG', false),
Extension Loading
node_modules/@tiptap/extension-*.npm cache clean --force
npm install
Livewire Updates
public $content = '';
Config Overrides
php artisan config:clear after modifying filament-tiptap-editor.php.Customizing the Editor Instance Pass a callback to modify the Tiptap editor instance:
TiptapEditor::make('content')
->editor(function ($editor) {
$editor
->addCommands({
toggleBold: () => editor.chain().focus().toggleBold().run(),
});
}),
Event Listeners
Listen to editor events (e.g., onUpdate):
->script(<<<'JS'
document.addEventListener('tiptap-editor-update', function(e) {
console.log('Content updated:', e.detail.html);
});
JS)
Theming Override CSS variables in your app’s assets:
.tiptap-editor {
--tiptap-font-family: 'Inter', sans-serif;
--tiptap-color: #333;
}
Server-Side Processing Use model observers to process content on save:
class PostObserver
{
public function saved(Post $post)
{
$post->content = Str::of($post->content)->markdown(); // Convert HTML to MD
$post->save();
}
}
How can I help you explore Laravel packages today?