Getting started
Library
Components
Integrations
Filament RichEditor
The Media Library provides a plugin for Filament's RichEditor component, allowing users to insert images from the Media Library directly into the rich editor content. When a user clicks the toolbar button, a modal opens with a MediaPicker to select a file and an alt text field. The selected image is then inserted into the editor.
Images are stored by their ID rather than their URL. This means that the URL is resolved dynamically each time the content is loaded or rendered, which ensures that temporary URLs (e.g. for private S3 buckets) are always fresh and never expire.
Setup
Set up the model
It is recommended that your model implements Filament's HasRichContent interface and use the InteractsWithRichContent trait. Then, register the MediaPlugin in the setUpRichContent() method:
use Filament\Forms\Components\RichEditor\Models\Concerns\InteractsWithRichContent;
use Filament\Forms\Components\RichEditor\Models\Contracts\HasRichContent;
use Illuminate\Database\Eloquent\Model;
use RalphJSmit\Filament\MediaLibrary\Filament\Forms\Components\RichEditor\Plugins\MediaPlugin;
class Post extends Model implements HasRichContent
{
use InteractsWithRichContent;
protected function setUpRichContent(): void
{
$plugin = MediaPlugin::make();
$this
->registerRichContent('content')
->plugins([$plugin])
->fileAttachmentProvider($plugin->getFileAttachmentProvider());
}
}
The registerRichContent() method should receive the name of the attribute that contains the rich content (e.g. 'content'). Make sure that this matches the name of the RichEditor field in your form.
The fileAttachmentProvider() call registers the file attachment provider, which is responsible for resolving image URLs when the editor loads existing content and when the content is rendered.
Add the toolbar button
In your Filament resource or form, add the insertFile button to the RichEditor toolbar using the enableToolbarButtons() method:
use Filament\Forms\Components\RichEditor;
RichEditor::make('content')
->enableToolbarButtons([
'insertFile',
])
This adds a photo icon button to the toolbar. When clicked, it opens a modal with a MediaPicker to select a file and a text input for alt text.
Render content
When rendering the content outside of Filament (e.g. on a frontend page), you can use the renderRichContent() method on the model. This will automatically resolve image URLs using the configured file attachment provider:
{!! $post->renderRichContent('content') !!}
Alternatively, you can use the getRichContentAttribute() method, which returns an Htmlable object:
{{ $post->getRichContentAttribute('content') }}
Both methods will automatically generate fresh URLs for all images in the content.
When using a text column in a Filament table or a text entry in an infolist, Filament will render the rich content automatically. You don't need to manually call
renderRichContent()in that case.
JSON storage (optional)
The integration works with both HTML and JSON storage. If you prefer to store content as JSON, add the json() call when registering the rich content attribute:
protected function setUpRichContent(): void
{
$plugin = MediaPlugin::make();
$this
->registerRichContent('content')
->json()
->plugins([$plugin])
->fileAttachmentProvider($plugin->getFileAttachmentProvider());
}
Make sure to also add the array cast to your model and call json() on the RichEditor field:
RichEditor::make('content')
->json()
->enableToolbarButtons([
'insertFile',
])
When storing as HTML, image IDs are preserved via the
data-idattribute on the<img>tag. When storing as JSON, the ID is stored as an attribute on the image node. Both formats work identically with the file attachment provider.
How it works
When a user inserts an image from the Media Library, the following data is stored on the image node:
| Attribute | Description |
|---|---|
| `id` | The primary key of the `MediaLibraryItem`. |
| `alt` | The alt text entered by the user. |
The src (URL) is generated on-the-fly and never persisted to the database. This happens automatically at three points:
- Loading the editor -- when existing content is loaded into the RichEditor, the
srcis refreshed for each image. - Saving content -- the
srcis stripped from the content before saving to the database, ensuring no stale or expired URLs are stored. - Rendering content -- when the content is rendered (via
renderRichContent()or in a Filament table/infolist), thesrcis resolved from the image ID.
This approach ensures that images always have a valid URL, even when using private storage disks that require temporary URLs.
Picking a conversion when inserting
When conversions are enabled on the MediaLibraryItemDriver, the insert-file modal shows an extra Conversion select. Pick a conversion (e.g. medium, thumb) to embed that specific size instead of the original. The conversion key is appended to the stored id as a composite identifier – so the choice persists across loads and the correct conversion URL is resolved at render time.
If no conversions are enabled, or the editor is inserting a non-image file, the select is hidden automatically.
Default alt text
When you insert an image, the Alt text field is pre-filled from the item's stored alt_text value. This keeps captions and alt attributes consistent across every place the image appears, and saves you from re-typing the same description per insertion. You can still override the alt text for a specific insertion if you want it to differ from the default.