Laravel Nova Tiptap Editor Field

June 11, 2026 · View on GitHub

Version Issues Licence

Laravel Nova Tiptap Editor Field

A powerful rich text editor for Laravel Nova built on TipTap v3.

Nova TipTap Editor

Warning

When updating from manogi/nova-tiptap, replace all instances of Manogi\Tiptap\Tiptap with Marshmallow\Tiptap\Tiptap.

Important

This is a maintained fork of the original package with Nova 5 support.

Installation

composer require marshmallow/nova-tiptap

Add the use statement to your Nova resource:

use Marshmallow\Tiptap\Tiptap;

Basic Usage

Tiptap::make('Content')

This provides a simple editor with bold and italic buttons only.

Button Configuration

Create a fully-featured editor by configuring your desired buttons:

Tiptap::make('Content')
  ->buttons([
    'heading', 'bold', 'italic', '|', 'link', 'bulletList', 'orderedList',
    // Add more buttons as needed
  ])

Available Buttons

ButtonDescription
headingText headings dropdown (H1, H2, H3, etc.)
headingDropdownAlias for heading
listDropdownBullet and ordered lists in a dropdown
alignDropdownText alignment options in a dropdown
colorColor text formatting
backgroundColorBackground color formatting
boldBold text formatting
italicItalic text formatting
strikeStrikethrough text
underlineUnderline text
bulletListUnordered/bullet list
orderedListOrdered/numbered list
linkHyperlinks to URLs or files
codeInline code formatting
codeBlockBlock code with optional syntax highlighting
blockquoteBlock quotes
imageInsert and upload images via modal
imageUploadInsert a drag & drop upload zone
tableCreate and edit tables
tableAlternativeAlternative UI for creating and editing tables. Supports coloring cell's background and border.
textAlignText alignment options
rtlRight-to-left text direction
horizontalRuleHorizontal divider line
hardBreakHard line break
historyUndo/redo functionality
editHtmlHTML source code editor
clearFormattingRemove inline formatting and reset selected content to plain paragraph/list structure
|Vertical divider in toolbar (special)
brLine break in toolbar (special)

Feature Configuration

Headings

The heading button displays a dropdown with heading levels and paragraph option:

Tiptap::make('Content')
  ->buttons(['heading'])
  ->headingLevels([2, 3, 4]) // Only allow H2, H3, H4 (default: H1-H3)

Lists

Use listDropdown for a compact dropdown with bullet and ordered list options:

Tiptap::make('Content')
  ->buttons(['listDropdown'])

Or use separate buttons:

Tiptap::make('Content')
  ->buttons(['bulletList', 'orderedList'])
Tiptap::make('Content')
  ->buttons(['link'])
  ->linkSettings([
    'withFileUpload' => false, // Disable file upload option (default: true)
  ])
  ->fileSettings([
    'disk' => 'public', // Storage disk to use (default: 'public')
    'path' => 'links',  // Path within disk (default: root folder)
  ])

Images

Tiptap::make('Content')
  ->buttons(['image'])
  ->imageSettings([
    'disk' => 'public',     // Storage disk to use
    'path' => 'uploads/images', // Path within disk
    'withFileUpload' => true,   // Allow file uploads (default: true)
  ])

Drag & Drop Upload

Images can be dragged directly into the editor or pasted from the clipboard. They will automatically upload using your imageSettings configuration.

Image Upload Zone

Use the imageUpload button to insert a TipTap-style drop zone in the editor:

Tiptap::make('Content')
  ->buttons(['imageUpload', 'image'])
  ->imageSettings([
    'disk' => 'public',
    'path' => 'uploads/images',
  ])

Plain Text Paste

When enabled, users can paste as plain text by using Shift + Paste in the editor. This strips formatting from sources like Word or websites before insertion.

Tiptap::make('Content')
  ->enablePlainTextPasteShortcut()

Bubble Menu

A floating toolbar appears when text is selected. Configure which buttons appear:

Tiptap::make('Content')
  ->bubbleMenuButtons(['bold', 'italic', '|', 'link', 'color'])

Available bubble menu buttons: bold, italic, strike, underline, code, highlight, subscript, superscript, link, color, backgroundColor, | (separator)

To disable the bubble menu:

Tiptap::make('Content')
  ->withoutBubbleMenu()

Text Alignment

Use alignDropdown for a compact dropdown or textAlign for separate buttons:

Tiptap::make('Content')
  ->buttons(['alignDropdown']) // Dropdown with all alignment options
  // or
  ->buttons(['textAlign']) // Separate buttons for each alignment
  ->alignments(['left', 'center', 'right', 'justify']) // Available alignments
  ->defaultAlignment('left') // Default text alignment

Color options

Tiptap::make('Content')
  ->buttons(['color'])
  ->colors(['#f1f1f1']) // Available colors in HEX

Background color options

Tiptap::make('Content')
  ->buttons(['backgroundColor'])
  ->backgroundColors(['#f1f1f1']) // Available background colors in HEX

Table cell background color options

Tiptap::make('Content')
  ->buttons(['tableAlternative'])
  ->tableCellBackgroundColors(['#f1f1f1']) // Available table cell background colors in HEX

Table cell border color options

Tiptap::make('Content')
  ->buttons(['tableAlternative'])
  ->tableCellBorderColors(['#f1f1f1']) // Available table cell border colors in HEX

RTL Support

Tiptap::make('Content')
  ->buttons(['rtl']) // Adds button to toggle RTL mode

Code Options

Two code formatting options are available:

  • code - Inline code formatting (<code>text</code>)
  • codeBlock - Block code formatting (<pre><code>text</code></pre>)

Enable syntax highlighting for code blocks:

Tiptap::make('Content')
  ->buttons(['codeBlock'])
  ->syntaxHighlighting()

HTML Editing

Tiptap::make('Content')
  ->buttons(['editHtml'])
  ->htmlTheme('night') // Theme for HTML code editor (default: 'material')

Available themes are listed on CodeMirror's theme demo page.

Placeholder

Tiptap::make('Content')
  ->placeholder('Start writing...') // Placeholder shown when the editor is empty

JSON Storage

Tiptap::make('Content')
  ->saveAsJson() // Store content as JSON instead of HTML

Empty Content Sanitization

By default, when a TipTap editor is empty, it returns an empty paragraph with styling (e.g., <p style="text-align: left"></p>). If you prefer to get an empty string instead (especially useful for translatable fields), you can enable the sanitization feature:

Tiptap::make('Content')
  ->sanitizeEmptyContent() // Return empty string for empty editor content

Image Pruning

When enabled, this feature automatically removes uploaded images from storage when they are deleted from the TipTap content. Only images with tt-mode="file" (uploaded files) will be pruned, not external URLs with tt-mode="url".

Enable Globally

First, publish the configuration file:

php artisan vendor:publish --tag=nova-tiptap-config

Then enable image pruning in config/nova-tiptap.php:

return [
    'prune_images' => true,
    // ... other config options
];

Enable Per Field

You can also enable image pruning for specific fields:

Tiptap::make('Content')
  ->buttons(['image'])
  ->imageSettings([
    'disk' => 'public',
    'path' => 'uploads/images',
  ])
  ->pruneImages() // Enable image pruning for this field

How It Works

The system tracks uploaded images by their tt-mode="file" attribute. When content is updated:

  1. It extracts all uploaded image URLs from the old content
  2. It extracts all uploaded image URLs from the new content
  3. Images that exist in the old content but not in the new content are deleted from storage
  4. External images with tt-mode="url" are never deleted

Read-Only Mode

The Tiptap field supports Nova's native readonly functionality. When in readonly mode, the editor will display the content without allowing edits:

Tiptap::make('Content')
  ->readonly() // Make the field readonly based on your logic

You can also conditionally set the readonly state:

Tiptap::make('Content')
  ->readonly(function ($request) {
      return !$request->user()->isAdmin();
  })

Index View Visibility

Like other rich text fields, this field is hidden from index views. You can display it using a computed field.

Configuration

Most options can be set per field as shown above. To change the global defaults, publish the configuration file:

php artisan vendor:publish --tag=nova-tiptap-config

This creates config/nova-tiptap.php with the following options:

KeyDefaultDescription
prune_imagesfalseGlobally enable automatic pruning of uploaded images that are removed from content.
image_storage.diskpublicDefault storage disk for image uploads when not set on the field.
image_storage.path''Default path within the disk for image uploads.
file_storage.diskpublicDefault storage disk for file uploads when not set on the field.
file_storage.path''Default path within the disk for file uploads.
upload.max_image_size5242880 (5MB)Maximum image upload size in bytes.
upload.max_file_size10485760 (10MB)Maximum file upload size in bytes.
upload.allowed_image_extensionsjpg, jpeg, png, gif, webp, svgAllowed extensions for image uploads.
upload.allowed_file_extensionspdf, doc, docx, xls, …, mp4, mov, wmvAllowed extensions for file uploads.
upload.allowed_diskspublic, localDisks permitted for uploads. For security, only listed disks are allowed.
upload.strict_mime_checkingtrueValidate that file content matches its extension.

Credits

This package is maintained by Marshmallow and is a fork of the original bastihilger/nova-tiptap by Sebastian Hilger.

Security

If you discover any security related issues, please email security@marshmallow.dev instead of using the issue tracker.

License

The MIT License (MIT). Please see License File for more information.