mateuslecchi / filament-rich-editor-extender
A set of extra extensions for Filament RichEditor
Package info
github.com/mateuslecchi/filament-rich-editor-extender
pkg:composer/mateuslecchi/filament-rich-editor-extender
Requires
- php: ^8.4
- filament/forms: ^5.0
- illuminate/contracts: ^13.0
- spatie/laravel-package-tools: ^1.92
- ueberdosis/tiptap-php: ^2.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pao: ^1.1
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^11.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.35
README
Extra goodies for the Filament Forms RichEditor (v5). This package ships small, focused extensions that plug straight into your existing editor.
Currently included:
- YouTube embeds.
- More to come...
Requirements
| Package Version | PHP Version | Laravel Version | Filament Forms Version |
|---|---|---|---|
| 1.x | 8.4+ | 13+ | 5.x |
Installation
You can install the package via composer:
composer require mateuslecchi/filament-rich-editor-extender
Then run the package installer:
php artisan filament-rich-editor-extender:install
Usage
Once installed, all tools will be available for all RichEditor instances. The plugin registers itself automatically, so no additional configuration is required.
YouTube
Add the youtube button to your editor's toolbar. It opens a modal asking for a YouTube URL and inserts the video as an embed.
use Filament\Forms\Components\RichEditor; RichEditor::make('content') ->label('Content') ->toolbarButtons([ 'youtube', ]);
Embeds use the privacy-enhanced youtube-nocookie.com domain by default.
Storage modes (HTML or JSON)
Filament can store RichEditor content as HTML (its native default) or as a structured JSON document. The YouTube embed works in both — pick what fits your app:
| HTML (default) | JSON | |
|---|---|---|
| Column | text / longText, no cast |
json, or cast the attribute to array |
| Field | ->youtubeStorage() (or nothing) |
->youtubeStorage('json') (or Filament's ->json()) |
| Stored value | ready-to-use HTML | structured document |
Use the per-field helper to follow the package's configured default:
use Filament\Forms\Components\RichEditor; RichEditor::make('content') ->youtubeStorage() // HTML by default; ->youtubeStorage('json') for JSON ->toolbarButtons(['youtube']);
The default mode is read from config('filament-rich-editor-extender.storage') ('html' out of the box). The helper is opt-in per field — it never changes the storage mode of your other RichEditor fields. For JSON mode, remember to make the column array-castable:
protected function casts(): array { return ['content' => 'array']; // JSON mode only }
⚠️ Switching an existing field between HTML and JSON changes the stored format. Migrate the column/cast and the existing rows accordingly — the package does not convert data for you.
Displaying
When you render stored content, the renderer needs to know about the plugin so it can turn the YouTube node back into an <iframe>. Filament's global editor configuration is not inherited by RichContentRenderer, so register the plugin on the content explicitly.
The idiomatic way is via the model, using Filament's HasRichContent:
use Filament\Forms\Components\RichEditor\Models\Concerns\InteractsWithRichContent; use Filament\Forms\Components\RichEditor\Models\Contracts\HasRichContent; use MateusLecchi\FilamentRichEditorExtender\Plugins\YoutubePlugin; class Post extends Model implements HasRichContent { use InteractsWithRichContent; protected function setUpRichContent(): void { $this->registerRichContent('content') ->plugins([YoutubePlugin::make()]); } }
{!! $post->renderRichContent('content') !!}
Or render directly:
use Filament\Forms\Components\RichEditor\RichContentRenderer; use MateusLecchi\FilamentRichEditorExtender\Plugins\YoutubePlugin; RichContentRenderer::make($post->content) ->plugins([YoutubePlugin::make()]) ->toHtml();
Sanitization
Filament renders rich content through Str::sanitizeHtml(), whose sanitizer strips <iframe> by default — which would remove the embed. To prevent that, this package extends Filament's application-wide sanitizer config to allow a YouTube <iframe>, restricting its src to YouTube hosts (any other host's iframe src is dropped). Other media is unaffected.
If you'd rather control this, publish the config and tweak it:
php artisan vendor:publish --tag=filament-rich-editor-extender-config
// config/filament-rich-editor-extender.php 'youtube' => [ 'sanitizer' => [ 'enabled' => true, // set false to opt out of the global change 'allowed_hosts' => ['youtube-nocookie.com', 'youtube.com'], ], ],
Translations
The package ships with translations (currently en and pt_BR). To customize them in your app, publish the language files:
php artisan vendor:publish --tag=filament-rich-editor-extender-translations
They will be copied to lang/vendor/filament-rich-editor-extender. Contributions with new locales are welcome.
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.