| Install | |
|---|---|
composer require athphane/filament-editorjs |
|
| Latest Version: | v2.5.0 |
| PHP: | ^8.3 |
A premium EditorJS field for Filament with seamless Spatie Media Library integration and a robust rendering system.
Filament EditorJS brings the power of Editor.js to your Filament admin panel, allowing you to create rich, block-based content with ease. It handles image uploads out of the box using Livewire and Spatie's Media Library, and provides a powerful rendering engine to display your content on the frontend with Tailwind CSS support.

prose).Install the package via composer:
composer require athphane/filament-editorjs
Publish the configuration file:
php artisan vendor:publish --tag="filament-editorjs-config"
Your model must implement Spatie's HasMedia interface and use the ModelHasEditorJsComponent trait provided by this package.
use Athphane\FilamentEditorjs\Traits\ModelHasEditorJsComponent;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Post extends Model implements HasMedia
{
use InteractsWithMedia;
use ModelHasEditorJsComponent;
// By default, it expects a 'content' column (json)
// and registers a 'content_images' media collection.
}
Add the plugin to your Filament Panel provider (usually AdminPanelProvider.php):
use Athphane\FilamentEditorjs\FilamentEditorjsPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
FilamentEditorjsPlugin::make(),
]);
}
Simply use the EditorjsTextField in your form schema:
use Athphane\FilamentEditorjs\Forms\Components\EditorjsTextField;
public static function form(Form $form): Form
{
return $form
->schema([
EditorjsTextField::make('content')
->placeholder('Start writing your masterpiece...')
->columnSpanFull(),
]);
}
Displaying your content is just as easy:
{{-- In your Blade view --}}
{!! \Athphane\FilamentEditorjs\FilamentEditorjs::renderContent($post->content) !!}
Note: For the best experience, ensure you have the @tailwindcss/typography plugin installed.
This package allows you to customize the editor tools dynamically.
You can add any Editor.js compatible tool by registering it in Javascript and then enabling it in PHP.
Add your custom tool to the global window.filamentEditorJsTools registry:
import LinkTool from '@editorjs/link'
window.filamentEditorJsTools = window.filamentEditorJsTools || {}
window.filamentEditorJsTools.linkTool = LinkTool
Use the addPlugin method on your field:
EditorjsTextField::make('content')
->addPlugin('linkTool', [
'endpoint' => route('editorjs.link-tool-parser'),
])
You can extend the rendering engine by adding custom renderers for specific block types.
use Athphane\FilamentEditorjs\Renderers\BlockRenderer;
class CustomBlockRenderer extends BlockRenderer
{
public function render(array $block): string
{
return view('renderers.custom-block', [
'data' => $block['data'],
])->render();
}
public function getType(): string
{
return 'custom-block-type';
}
}
Register it in your AppServiceProvider:
use Athphane\FilamentEditorjs\FilamentEditorjs;
public function boot()
{
FilamentEditorjs::addRenderer(new CustomBlockRenderer());
}
When creating a custom renderer, you can define how it contributes to the reading time calculation by implementing the getWordCount() method:
use Athphane\FilamentEditorjs\Renderers\BlockRenderer;
class CustomBlockRenderer extends BlockRenderer
{
public function render(array $block): string
{
return view('renderers.custom-block', [
'data' => $block['data'],
])->render();
}
public function getType(): string
{
return 'custom-block-type';
}
public function getWordCount(array $block): int
{
$text = $block['data']['content'] ?? '';
return str_word_count(strip_tags($text));
}
}
You can calculate the reading time for your content:
use Athphane\FilamentEditorjs\FilamentEditorjs;
// Get reading time string (e.g., "5 min read")
$readingTime = FilamentEditorjs::readingTime($post->content);
// Get total word count
$wordCount = FilamentEditorjs::countWords($post->content);
Built-in Block Types:
Configure words per minute in config/filament-editorjs.php:
'reading_time' => [
'words_per_minute' => 225, // Default
],
The config/filament-editorjs.php file allows you to define different tool profiles:
'profiles' => [
'default' => [
'header', 'image', 'delimiter', 'list', 'underline', 'quote', 'table',
],
'pro' => [
'header', 'image', 'delimiter', 'list', 'underline', 'quote', 'table',
'raw', 'code', 'inline-code', 'style', 'checklist',
],
],
Switch between profiles in your form:
EditorjsTextField::make('content')->tools('pro')
The package includes powerful code block functionality with language selection and syntax highlighting powered by Shiki.
Code blocks work out of box with automatic syntax highlighting. Simply type your desired language in the small input field located in the top-right corner of the code block:
EditorjsTextField::make('content')
You can configure code highlighting behavior using the following methods:
EditorjsTextField::make('content')
->codeTheme('github-dark') // Set syntax highlighting theme
->codeLanguages(['php', 'js']) // Restrict available languages (future enhancement)
->showLanguageLabel(true) // Show/hide language label
->enableCopyButton(true) // Enable copy button (future)
->enableLineHighlighting(true) // Enable line highlighting
When you insert a code block in the editor, you'll see a small text input in the top-right corner. Simply type your programming language there:
php for PHP codejavascript or js for JavaScriptpython or py for Python codego, rust, ruby, etc.)The input is unobtrusive and allows you to smoothly see your code while specifying the language. Common language codes include:
javascript, typescript, html, css, php, vue, sveltec, c++, rust, go, assemblypython, ruby, bash, shell, powershelljson, xml, yaml, tomlsql, plsql, sparqlYou can mark specific lines with different visual states:
{
"type": "code",
"data": {
"code": "const x = 1;\nconst y = 2;\nconst z = 3;",
"languageCode": "javascript",
"highlightLines": [1, 3],
"addLines": [2],
"deleteLines": [],
"focusLines": []
}
}
Available line modes:
highlightLines: Yellow background for important linesaddLines: Green background for new linesdeleteLines: Red background for removed linesfocusLines: Blue background with ring for focusShiki supports many VSCode themes. Popular options include:
github-light (default)github-darknordvitesse-darkone-dark-promonokaidraculaUpdate config/filament-editorjs.php to set global defaults:
'code' => [
'default_theme' => 'github-light',
'line_highlighting' => true,
'supported_line_modes' => ['highlight', 'add', 'delete', 'focus'],
],
Existing code blocks without a languageCode will default to plaintext with basic formatting. The renderer gracefully handles missing data and falls back to safe HTML escaping.
All code block styles are included in the main CSS file. You can customize the appearance by overriding Tailwind classes in your project:
/* Custom code block styles */
.code-block-wrapper {
/* Your custom styles */
}
.highlighted {
/* Custom highlight style */
}
Basic Code Block:
Type "javascript" in top-right input
→ Enter your code
→ Gets syntax highlighted automatically
Code with Line Highlights:
Highlight lines 1 and 3
→ Lines get yellow background
→ Great for tutorials and explanations
Dark Theme:
Use in dark mode environment
→ Shiki automatically switches theme
→ Consistent with your design
Multiple Languages:
Type "php" for PHP code
Type "python" for Python code
Type "rust" for Rust code
→ Each gets proper highlighting
Please refer to the Upgrade Guide when moving between major versions.
composer test
Contributions are welcome! Please see CONTRIBUTING.md for details.
The MIT License (MIT). Please see License File for more information.