PHPackages                             height99/filament-tiptap-editor - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. height99/filament-tiptap-editor

ActivePackage[Framework](/categories/framework)

height99/filament-tiptap-editor
===============================

A Tiptap integration for Filament Admin/Forms.

v0.3.1(2y ago)036MITPHPPHP ^8.1

Since Mar 18Pushed 2y agoCompare

[ Source](https://github.com/height99/filament-tiptap-editor)[ Packagist](https://packagist.org/packages/height99/filament-tiptap-editor)[ GitHub Sponsors](https://github.com/awcodes)[ RSS](/packages/height99-filament-tiptap-editor/feed)WikiDiscussions 3.x Synced 1mo ago

READMEChangelog (7)Dependencies (11)Versions (8)Used By (0)

Filament Tiptap Editor
======================

[](#filament-tiptap-editor)

A Tiptap integration for Filament Admin/Forms.

[![tiptap-editor-og](https://camo.githubusercontent.com/21f6c7b4645d8e887bd1aa738fad5fd8a9f90ea98bf2cc4e665000cf21ac9ecb/68747470733a2f2f7265732e636c6f7564696e6172792e636f6d2f61772d636f6465732f696d6167652f75706c6f61642f775f313230302c665f6175746f2c715f6175746f2f706c7567696e732f7469707461702d656469746f722f6177636f6465732d7469707461702d656469746f722e6a7067)](https://camo.githubusercontent.com/21f6c7b4645d8e887bd1aa738fad5fd8a9f90ea98bf2cc4e665000cf21ac9ecb/68747470733a2f2f7265732e636c6f7564696e6172792e636f6d2f61772d636f6465732f696d6167652f75706c6f61642f775f313230302c665f6175746f2c715f6175746f2f706c7567696e732f7469707461702d656469746f722f6177636f6465732d7469707461702d656469746f722e6a7067)

Installation
------------

[](#installation)

Install the package via composer

```
composer require height99/filament-tiptap-editor
```

In an effort to align with Filament's theming methodology you will need to use a custom theme to use this plugin.

> **Note**If you have not set up a custom theme and are using a Panel follow the instructions in the [Filament Docs](https://filamentphp.com/docs/3.x/panels/themes#creating-a-custom-theme) first. The following applies to both the Panels Package and the standalone Forms package.

1. Import the plugin's stylesheet and tippy.js stylesheet (if not already included) into your theme's css file.

```
@import '/height99/filament-tiptap-editor/resources/css/plugin.css';
```

2. Add the plugin's views to your `tailwind.config.js` file.

```
content: [
    ...
    '/height99/filament-tiptap-editor/resources/**/*.blade.php',
]
```

3. Add the `tailwindcss/nesting` plugin to your `postcss.config.js` file.

```
module.exports = {
    plugins: {
        'tailwindcss/nesting': {},
        tailwindcss: {},
        autoprefixer: {},
    },
}
```

4. Rebuild your custom theme.

```
npm run build
```

Upgrading from 2.x to 3.x
-------------------------

[](#upgrading-from-2x-to-3x)

1. Output is now set with an Enum, please update your files to use `TiptapOutput` in all place where you are setting the output, including the config file.
2. `barebone` profile setting was renamed to `minimal`

Usage
-----

[](#usage)

The editor extends the default Field class so most other methods available on that class can be used when adding it to a form.

```
use FilamentTiptapEditor\TiptapEditor;
use FilamentTiptapEditor\Enums\TiptapOutput;

TiptapEditor::make('content')
    ->profile('default|simple|minimal|none|custom')
    ->tools([]) // individual tools to use in the editor, overwrites profile
    ->disk('string') // optional, defaults to config setting
    ->directory('string or Closure returning a string') // optional, defaults to config setting
    ->acceptedFileTypes(['array of file types']) // optional, defaults to config setting
    ->maxFileSize('integer in KB') // optional, defaults to config setting
    ->output(TiptapOutput::Html) // optional, change the format for saved data, default is html
    ->maxContentWidth('5xl')
    ->required();
```

### Rendering content in Blade files

[](#rendering-content-in-blade-files)

If you are storing your content as JSON then you will likely need to parse the data to HTML for output in Blade files. To help with this there is a helper function `tiptap_converter` that will convert the data to one of the three supported Tiptap formats.

Styling the output is entirely up to you.

```
{!! tiptap_converter()->asHTML($post->content) !!}
{!! tiptap_converter()->asJSON($post->content) !!}
{!! tiptap_converter()->asText($post->content) !!}
```

#### Table of Contents

[](#table-of-contents)

If you are using the `heading` tool in your editor you can also generate a table of contents from the headings in the content. This is done by passing the content to the `asHTML()` method and setting the `toc` option to `true`. You can also pass a `maxDepth` option to limit the depth of headings to include in the table of contents.

```

{!! tiptap_converter()->asHTML($post->content, toc: true, maxDepth: 3) !!}

{!! tiptap_converter()->asToc($post->content, maxDepth: 3) !!}
```

Config
------

[](#config)

The plugin will work without publishing the config, but should you need to change any of the default settings you can publish the config file with the following Artisan command:

```
php artisan vendor:publish --tag="filament-tiptap-editor-config"
```

### Profiles / Tools

[](#profiles--tools)

The package comes with 3 profiles (or toolbars) out of the box. You can also use a pipe `|` to separate tools into groups. The default profile is the full set of tools.

```
'profiles' => [
    'default' => [
        'heading', 'bullet-list', 'ordered-list', 'checked-list', 'blockquote', 'hr',
        'bold', 'italic', 'strike', 'underline', 'superscript', 'subscript', 'lead', 'small', 'align-left', 'align-center', 'align-right',
        'link', 'media', 'oembed', 'table', 'grid-builder', 'details',
        'code', 'code-block', 'source',
    ],
    'simple' => [
        'heading', 'hr', 'bullet-list', 'ordered-list', 'checked-list',
        'bold', 'italic', 'lead', 'small',
        'link', 'media',
    ],
    'minimal' => [
        'bold', 'italic', 'link', 'bullet-list', 'ordered-list',
    ],
],
```

See `filament-tiptap-editor.php` config file for modifying profiles to add / remove buttons from the editor or to add your own.

Tools can also be added on a per-instance basis by using the `->tools()` modifier to overwrite the profile set for the instance. A full list of tools can be found in the `filament-tiptap-editor.php` config file under the default profile setting.

### Media / Images

[](#media--images)

```
[
    'accepted_file_types' => ['image/jpeg', 'image/png', 'image/webp', 'image/svg+xml', 'application/pdf'],
    'disk' => 'public',
    'directory' => 'images',
    'visibility' => 'public',
    'preserve_file_names' => false,
    'max_file_size' => 2042,
    'image_crop_aspect_ratio' => null,
    'image_resize_target_width' => null,
    'image_resize_target_height' => null,
]
```

### Output format

[](#output-format)

Tiptap has 3 different output formats. See:

If you want to change the output format that is stored in the database you can change the default config or specify it in each instance.

```
use FilamentTiptapEditor\Enums\TiptapOutput;

TiptapEditor::make('content')
    ->output(FilamentTiptapEditor\TiptapOutput::Json);
```

> **Note**If you want to store the editor content as array / json you have to set the database column as `longText` or `json` type. And cast it appropriately in your model class.

```
// in your migration
$table->json('content');

// in your model
protected $casts = [
    'content' => 'json' // or 'array'
];
```

### RTL Support

[](#rtl-support)

In order for things like text align to work properly with RTL languages you can switch the `direction` key in the config to 'rtl'.

```
// config/filament-tiptap-editor.php
'direction' => 'rtl'
```

### Max Content Width

[](#max-content-width)

To adjust the max content width of the editor globally set `max_content_width`key in the config to one of the tailwind max width sizes or `full` for full width. This could also be set on a per-instance basis with the `->maxContentWidth()` method.

```
'max_content_width' => 'full'
```

```
use FilamentTiptapEditor\TiptapEditor;

TiptapEditor::make('content')
    ->maxContentWidth('3xl');
```

Overrides
---------

[](#overrides)

The Link and Media modals are built using Filament Form Component Actions. This means it is easy enough to swap them out with your own implementations.

### Link Modal

[](#link-modal)

You may override the default Link modal with your own Action and assign to the `link_action` key in the config file. Make sure the default name for your action is `filament_tiptap_link`.

See `vendor/height99/filament-tiptap-editor/src/Actions/LinkAction.php` for implementation.

### Media Modal

[](#media-modal)

You may override the default Media modal with your own Action and assign to the `media_action` key in the config file. Make sure the default name for your action is `filament_tiptap_media`.

See `vendor/height99/filament-tiptap-editor/src/Actions/MediaAction.php` for implementation.

### Initial height of editor field

[](#initial-height-of-editor-field)

You can add extra input attributes to the field with the `extraInputAttributes()` method. This allows you to do things like set the initial height of the editor.

```
TiptapEditor::make('content')
    ->extraInputAttributes(['style' => 'min-height: 12rem;']),
```

Bubble and Floating Menus
-------------------------

[](#bubble-and-floating-menus)

By default, the editor uses Bubble and Floating menus to help with creating content inline, so you don't have to use the toolbar. If you'd prefer to not use the menus you can disable them on a per-instance basis or globally in the config file.

```
TiptapEditor::make('content')
    ->disableFloatingMenus()
    ->disableBubbleMenus();
```

```
'disable_floating_menus' => true,
'disable_bubble_menus' => true,
```

You can also provide you own tools to for the floating menu, should you choose. Defaults can be overwritten via the config file.

```
TiptapEditor::make('content')
    ->floatingMenuTools(['grid-builder', 'media', 'link'])
```

```
'floating_menu_tools' => ['media', 'grid-builder', 'details', 'table', 'oembed', 'code-block']
```

Grid layouts
------------

[](#grid-layouts)

When using the `grid` tool, you can customize the available layouts in the dropdown by passing them to the `gridLayouts()` method:

```
TiptapEditor::make('content')
    ->gridLayouts([
        'two-columns',
        'three-columns',
        'four-columns',
        'five-columns',
        'fixed-two-columns',
        'fixed-three-columns',
        'fixed-four-columns',
        'fixed-five-columns',
        'asymmetric-left-thirds',
        'asymmetric-right-thirds',
        'asymmetric-left-fourths',
        'asymmetric-right-fourths',
    ]);
```

Custom Blocks
-------------

[](#custom-blocks)

> **Note**To use custom blocks you must store your content as JSON.

There are 3 components you need to create a custom block for Tiptap Editor.

- A block class that extends `TiptapBlock` and defines the settings for the block.
- A 'preview' blade file
- A 'rendered' blade file

### Creating a custom block

[](#creating-a-custom-block)

#### Block class

[](#block-class)

```
use FilamentTiptapEditor\TiptapBlock;

class BatmanBlock extends TiptapBlock
{
    public string $preview = 'blocks.previews.batman';

    public string $rendered = 'blocks.rendered.batman';

    public function getFormSchema(): array
    {
        return [
            TextInput::make('name'),
            TextInput::make('color'),
            Select::make('side')
                ->options([
                    'Hero' => 'Hero',
                    'Villain' => 'Villain',
                ])
                ->default('Hero')
        ];
    }
}
```

#### Static blocks

[](#static-blocks)

If you simply need a placeholder to output a block that doesn't have settings you can simply not provide a `getFormSchema` method and no modal will be shown and blocks will be directly inserted into the editor.

```
use FilamentTiptapEditor\TiptapBlock;

class StaticBlock extends TiptapBlock
{
    public string $preview = 'blocks.previews.static';

    public string $rendered = 'blocks.rendered.static';
}
```

#### Modal width, slide overs and icons

[](#modal-width-slide-overs-and-icons)

***Note***: Currently, icons will only be show on the drag and drop block panel

```
class BatmanBlock extends TiptapBlock
{
    public string $width = 'xl';

    public bool $slideOver = true;

    public ?string $icon = 'heroicon-o-film';
}
```

#### Preview view

[](#preview-view)

Preview views are just standard blade views. Unfortunately, you cannot use Livewire components in a block preview as they will not work correctly due to the editor having to be wire:ignore.

`resources/views/blocks/previews/batman.blade.php`

```

        @php
            echo match($name) {
                'robin' => '🐤',
                'ivy' => '🥀',
                'joker' => '🤡',
                default => '🦇'
            }
        @endphp

        Name: {{ $name }}
        Color: {{ $color }}
        Side: {{ $side ?? 'Good' }}

```

#### Rendered view

[](#rendered-view)

Rendered views are normal blade files and can also be used to output livewire components with your block data.

`resources/views/blocks/rendered/batman.blade.php`

```

```

#### Registering your blocks with the editor

[](#registering-your-blocks-with-the-editor)

In the register method of a service provider you can add your blocks to the editor via `configureUsing`.

> **Note**You will also need to add the 'blocks' key where appropriate in your profiles in the tiptap config.

```
use App\TiptapBlocks\BatmanBlock;
use App\TiptapBlocks\StaticBlock;
use FilamentTiptapEditor\TiptapEditor;

TiptapEditor::configureUsing(function (TiptapEditor $component) {
    $component
        ->blocks([
            BatmanBlock::class,
            StaticBlock::class,
        ]);
});
```

By default, the drag and drop blocks panel will be open in the editor. If you want to change this you can use the `collapseBlocksPanel` modifier on the Editor instance or globally with `configureUsing`.

```
use App\TiptapBlocks\BatmanBlock;
use App\TiptapBlocks\StaticBlock;
use FilamentTiptapEditor\TiptapEditor;

TiptapEditor::configureUsing(function (TiptapEditor $component) {
    $component
        ->collapseBlocksPanel()
        ->blocks([...]);
});
```

Merge tags
----------

[](#merge-tags)

Merge tags can be used with JSON-based editor content to replace placeholders with dynamic content. Merge tags are defined in the `mergeTags()` method of the editor instance:

```
TiptapEditor::make('content')
    ->mergeTags([
        'first_name',
        'last_name',
    ])
```

To insert a merge tag, the user can either type `{{` to open an autocomplete menu, or drag a merge tag into the editor from the "blocks panel". You can remove the tags from the blocks panel using `showMergeTagsInBlocksPanel(false)`:

```
TiptapEditor::make('content')
    ->mergeTags([...])
    ->showMergeTagsInBlocksPanel(false)
```

Mentions
--------

[](#mentions)

Mentions can be used with JSON-based editor content to replace placeholders with dynamic content. Mentions tags are defined in the `mentions()` method of the editor instance: To insert a merge tag, the user can either type `@` to open an autocomplete menu.

```
TiptapEditor::make('content')
    ->mentions([
        'first_name',
        'last_name',
    ])
```

Usage in Standalone Forms Package
---------------------------------

[](#usage-in-standalone-forms-package)

If you are using any of the tools that require a modal (e.g. Insert media, Insert video, etc.), make sure to add `{{ $this->modal }}` to your view after the custom form:

```

    {{ $this->form }}

        Save

{{ $this->modal }}
```

Custom Extensions
-----------------

[](#custom-extensions)

You can add your own extensions to the editor by creating the necessary files and adding them to the config file extensions array.

***This only support CSS and JS with Vite.***

You can read more about custom extensions at .

### JS

[](#js)

First, create a directory for you custom extensions at `resources/js/tiptap` and add your extension files.

```
import { Node, mergeAttributes } from "@tiptap/core";

const Hero = Node.create({
    name: "hero",
    ...
})

export default Hero
```

Next, create at a file at `resources/js/tiptap/extensions.js` and add the following code.

***Note that when adding your extension to the array you must register them a key:array set.***

```
import Hero from "./hero.js";

window.TiptapEditorExtensions = {
    hero: [Hero]
}
```

### CSS

[](#css)

Create a css file for your custom extensions at `resources/css/tiptap/extensions.css`. All styles should be scoped to the parent class of `.tiptap-content`.

```
.tiptap-content {
    .hero-block {
        ...
    }
}
```

### Vite Config

[](#vite-config)

Now you need to add these to your `vite.config.js` file and run a build to generate the files.

```
export default defineConfig({
    plugins: [
        laravel({
            input: [
                ...
                'resources/js/tiptap/extensions.js',
                'resources/css/tiptap/extensions.css',
            ],
            refresh: true,
        }),
    ],
});
```

### PHP Parser

[](#php-parser)

You will also need to create a PHP version of your extension in order for the content to be read from the database and rendered in the editor or to your front end display. You are free to create this anywhere in your app, a good place is something like `app/TiptapExtensions/YourExtenion.php`.

You can read more about the php parsers at

```
namespace App\TiptapExtensions;

use Tiptap\Core\Node;

class Hero extends Node
{
    public static $name = 'hero';
    ...
}
```

### Toolbar Button

[](#toolbar-button)

You will also need to crate a dedicated view for you toolbar button. This should be placed somewhere in your app's `resources/views/components` directory. You are free to code the buttons as you see fit, but it is recommended to use the plugin's view components for uniformity.

```

    {{ $label }}

```

### Registering the Extensions

[](#registering-the-extensions)

Finally, you need to register your extensions in the config file and add the new extension to the appropriate `profile`.

```
'profiles' => [
    'minimal' => [
        ...,
        'hero',
    ],
],
'extensions_script' => 'resources/js/tiptap/extensions.js',
'extensions_styles' => 'resources/css/tiptap/extensions.css',
'extensions' => [
    [
        'id' => 'hero',
        'name' => 'Hero',
        'button' => 'tools.hero',
        'parser' => \App\TiptapExtensions\Hero::class,
    ],
],
```

Versioning
----------

[](#versioning)

This project follow the [Semantic Versioning](https://semver.org/) guidelines.

License
-------

[](#license)

Copyright (c) 2022 Adam Weston and contributors

Licensed under the MIT license, see [LICENSE.md](LICENSE.md) for details.

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 76% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

8

Last Release

780d ago

Major Versions

v0.3.1 → 3.x-dev2024-03-21

### Community

Maintainers

![](https://www.gravatar.com/avatar/cd7e0e9207bf4f08423b2966ec8e59280239cc0c9dc322f6fd02fa7884148a11?d=identicon)[safeguardingnetwork](/maintainers/safeguardingnetwork)

---

Top Contributors

[![awcodes](https://avatars.githubusercontent.com/u/3596800?v=4)](https://github.com/awcodes "awcodes (370 commits)")[![danharrin](https://avatars.githubusercontent.com/u/41773797?v=4)](https://github.com/danharrin "danharrin (25 commits)")[![G4b0rDev](https://avatars.githubusercontent.com/u/42324512?v=4)](https://github.com/G4b0rDev "G4b0rDev (20 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (11 commits)")[![fordiquez](https://avatars.githubusercontent.com/u/44981513?v=4)](https://github.com/fordiquez "fordiquez (9 commits)")[![jyrkidn](https://avatars.githubusercontent.com/u/2447042?v=4)](https://github.com/jyrkidn "jyrkidn (9 commits)")[![pboivin](https://avatars.githubusercontent.com/u/7805679?v=4)](https://github.com/pboivin "pboivin (6 commits)")[![maxime9446](https://avatars.githubusercontent.com/u/93121114?v=4)](https://github.com/maxime9446 "maxime9446 (5 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (5 commits)")[![rubenvanerk](https://avatars.githubusercontent.com/u/20305359?v=4)](https://github.com/rubenvanerk "rubenvanerk (4 commits)")[![lovemintblue](https://avatars.githubusercontent.com/u/72596738?v=4)](https://github.com/lovemintblue "lovemintblue (3 commits)")[![phuongvietvu0306](https://avatars.githubusercontent.com/u/11574441?v=4)](https://github.com/phuongvietvu0306 "phuongvietvu0306 (3 commits)")[![atmonshi](https://avatars.githubusercontent.com/u/1952412?v=4)](https://github.com/atmonshi "atmonshi (3 commits)")[![Orrison](https://avatars.githubusercontent.com/u/6799341?v=4)](https://github.com/Orrison "Orrison (2 commits)")[![liamseys](https://avatars.githubusercontent.com/u/10025985?v=4)](https://github.com/liamseys "liamseys (1 commits)")[![mohamedsabil83](https://avatars.githubusercontent.com/u/10126040?v=4)](https://github.com/mohamedsabil83 "mohamedsabil83 (1 commits)")[![mszabeh](https://avatars.githubusercontent.com/u/53317316?v=4)](https://github.com/mszabeh "mszabeh (1 commits)")[![MtDalPizzol](https://avatars.githubusercontent.com/u/3843774?v=4)](https://github.com/MtDalPizzol "MtDalPizzol (1 commits)")[![Askancy](https://avatars.githubusercontent.com/u/789702?v=4)](https://github.com/Askancy "Askancy (1 commits)")[![phpsa](https://avatars.githubusercontent.com/u/952595?v=4)](https://github.com/phpsa "phpsa (1 commits)")

---

Tags

frameworklaraveltiptapeditorwysiwygfilament

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/height99-filament-tiptap-editor/health.svg)

```
[![Health](https://phpackages.com/badges/height99-filament-tiptap-editor/health.svg)](https://phpackages.com/packages/height99-filament-tiptap-editor)
```

###  Alternatives

[awcodes/filament-tiptap-editor

A Tiptap integration for Filament Admin/Forms.

399865.2k21](/packages/awcodes-filament-tiptap-editor)[camya/filament-title-with-slug

TitleWithSlugInput - Easy Permalink Slugs for the FilamentPHP Form Builder (PHP / Laravel / Livewire)

13444.5k](/packages/camya-filament-title-with-slug)[awcodes/filament-sticky-header

A Filament Panel plugin to make page headers sticky when scrolling.

81116.8k1](/packages/awcodes-filament-sticky-header)[awcodes/filament-addons

A set of components / fields to extend Filament Admin.

3013.1k2](/packages/awcodes-filament-addons)[blendbyte/filament-title-with-slug

TitleWithSlugInput - Easy Permalink Slugs for the FilamentPHP Form Builder (PHP / Laravel / Livewire)

1322.4k3](/packages/blendbyte-filament-title-with-slug)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
