Overview
When using Filament's RichEditor with the link toolbar button
enabled, the action modal's form that collects the hyperlink details includes a checkbox for "Open in new tab".
This article outlines how to create a RichContentPlugin
implementation (extension for Filament's RichEditor) that behaves similarly to the default link functionality, but
without the aforementioned checkbox.
We'll accomplish this by
- Implementing a
RichEditorFilament plugin - Configuring our Filament form's
RichEditorto use the plugin
Use case
For when you'd prefer to not show the "Open in new tab" checkbox in the RichEditor link modal and default all created
links to always open in a new tab.
Assumptions
You have a working Laravel project with:
- Filament 4 installed and configured
- a form schema using Filament's
RichEditor
RichEditor Filament plugin
Filament's RichEditor was built with extensibility in mind. Anything you can do with TipTap, you can likely find a way
to do within the RichEditor.
Creating a plugin for Filament's RichEditor is done by creating a class that implements the RichContentPlugin
interface. For a more detailed breakdown of what each method in this interface is responsible for, see
Filament's documentation.
Implementing the plugin
Create the following class in a location that makes sense for your application's structure. This article uses
app/Filament/Forms/RichEditorPlugins/LinkNewTabPlugin.php.
1<?php 2 3namespace App\Support\Filament\Plugins; 4 5use Filament\Forms\Components\RichEditor; 6use Filament\Forms\Components\RichEditor\Actions\LinkAction; 7use Filament\Forms\Components\RichEditor\Plugins\Contracts\RichContentPlugin; 8use Filament\Forms\Components\RichEditor\RichEditorTool; 9use Filament\Schemas\Schema;10use Filament\Support\Icons\Heroicon;11 12class LinkNewTabPlugin implements RichContentPlugin13{14 public static function make(): static15 {16 return app(static::class);17 }18 19 public function getTipTapPhpExtensions(): array20 {21 return []; // PHP extension for links is already included by Filament's extensions22 }23 24 public function getTipTapJsExtensions(): array25 {26 return []; // JavaScript for links is already included by Filament's scripts27 }28 29 public function getEditorTools(): array30 {31 return [32 RichEditorTool::make('linkNewTab')33 ->label(__('filament-forms::components.rich_editor.tools.link'))34 ->action(arguments: '{ url: $getEditor().getAttributes(\'link\')?.href }')35 ->icon(Heroicon::Link)36 ->iconAlias('forms:components.rich-editor.toolbar.link'),37 ];38 }39 40 public function getEditorActions(): array41 {42 $linkAction = LinkAction::make();43 44 $schema = $linkAction->getSchema(Schema::make());45 $components = $schema->getComponents();46 $componentsWithoutShouldOpenInNewTabCheckbox = collect($components)47 ->reject(fn ($component) => $component->getName() === 'shouldOpenInNewTab')48 ->all();49 50 $linkActionFunction = $linkAction->getActionFunction();51 52 return [53 $linkAction54 ->name('linkNewTab')55 ->schema($componentsWithoutShouldOpenInNewTabCheckbox)56 ->action(function (array $arguments, array $data, RichEditor $component) use ($linkActionFunction) {57 $data['shouldOpenInNewTab'] = true;58 $linkActionFunction($arguments, $data, $component);59 }),60 ];61 }62}
The implementation above is based mostly off of Filament's preexisting implementation for the link tool. You can find
that implementation within this class.
Some changes made to Filament's original implementation include:
- in
getEditorTools, we are returning a single instantiatedRichEditorToolas a sole array element- the tool instance is named
linkNewTab, which we will reference when including the toolbar button in aRichEditorinstance. - the tool instance also uses an
actionbased off of Filament's implementation, but withoutshouldOpenInNewTabin the arguments object (because our action's form won't use it).
- the tool instance is named
- in
getEditorActions, we are returning an instance of Filament'sLinkActionaction, but overriding thename,schema, andactionconfigurations- we use
linkNewTabas the action name - we filter the components in the action's schema to exclude the
shouldOpenInNewTabcheckbox component - in the
actionfunction, we explicitly set the'shouldOpenInNewTab'key within the$dataarray totrueand then pass the data along to the originalLinkAction's action Closure
- we use
Using the plugin
Now we can use our plugin anywhere we configure a RichEditor (e.g. within a Filament Schema configuration).
Within the chain of methods on your RichEditor instance and within the array passed to the plugins method,
include an instance of the LinkNewTabPlugin class.
Then in the same method chain, within the array passed to the toolbarButtons method, place an element 'linkNewTab' wherever you'd like the
link button icon to appear in the editor's toolbar.
'link' entry in the array passed to the toolbarButtons method. Otherwise, a button for the original link tool provided by Filament will be included in addition to your new plugin's button.
1use App\Filament\Forms\RichEditorPlugins\LinkNewTabPlugin; 2 3// within your schema configuration 4$schema 5 ->components([ 6 // ... other schema components 7 RichEditor::make('content') 8 ->plugins([ 9 LinkNewTabPlugin::make(),10 ])11 ->toolbarButtons([12 // ... other toolbar buttons13 'linkNewTab',14 ]),15 ]);
Conclusion
By following the above steps, you can replace the link tool button provided out-of-the-box by Filament's RichEditor
with a custom plugin that slightly modifies the user's experience. The modal to specify details about the relevant
hyperlink will exclude the checkbox which denotes if the hyperlink should open a new tab. Instead, new hyperlinks created
with our plugin's interface will always open in a new tab.