Drag Context Menu
The DragContextMenu provides a drag handle with an extensive context menu for block-level operations. When you hover over any block in your editor, a drag handle appears on the left side. Clicking this handle opens a context menu with options to:
- Transform blocks into different types (headings, lists, blockquotes, etc.)
- Apply colors and highlights
- Copy, duplicate, or delete blocks
- Reset formatting
- Trigger AI assistance (if enabled)
- Download images (for image nodes)
Installation
Step 1: Set Up Your Project
If your project is already set up with the Tiptap CLI, skip ahead to Step 2: Configure Path Aliases.
If not, initialize a new project with the following command:
npx @tiptap/cli@latest initDuring setup, select your preferred framework and wait for the installation to complete. When prompted “Would you like to add a template or UI components to your project?”, select No — we’ll add the DragContextMenu component in the next steps.
Step 2: Configure Path Aliases
Navigate to your project directory. If you’re using Next.js, React Router, Laravel, or Astro, you can skip this step and move to the next one. Otherwise, follow the guide below to properly configure path aliases for your framework:
Step 3: Install the Component
Use the Tiptap CLI to install the DragContextMenu component and all of its dependencies:
npx @tiptap/cli@latest add drag-context-menuThis command will:
- Download all component files to your configured component directory
- Install npm dependencies (
@floating-ui/react,@tiptap/extension-drag-handle-react) - Install ~60 registry dependencies (hooks, UI primitives, icons, buttons, etc.)
- Create the necessary folder structure
Installed directories:
{components}/tiptap-ui/drag-context-menu/— Main component files{components}/hooks/— Custom hooks (use-tiptap-editor,use-mobile, etc.){components}/tiptap-ui-primitive/— UI primitives (button,menu,combobox, etc.){components}/tiptap-icons/— Icon components{components}/tiptap-ui/— Action button components (duplicate,copy,delete, etc.){components}/tiptap-extension/— Custom Tiptap extensions (UiState, etc.){components}/lib/— Utility functions
Step 4: Install Nodes
You may also want to install node components to ensure proper styling of blocks in your editor.
npx @tiptap/cli@latest add paragraph-node
npx @tiptap/cli@latest add heading-node
npx @tiptap/cli@latest add blockquote-node
npx @tiptap/cli@latest add code-block-node
npx @tiptap/cli@latest add list-node
npx @tiptap/cli@latest add horizontal-rule-nodeStep 5: Configure Styles
When you install the drag-context-menu component, its styles are included automatically.
Refer to the appropriate guide below for details on adding or customizing styles for your framework:
Step 6: Configure Your Editor Extensions
For starters, here’s a minimal set of extensions to get the DragContextMenu working:
import { EditorContent, EditorContext, useEditor } from '@tiptap/react'
import { StarterKit } from '@tiptap/starter-kit'
import { Highlight } from '@tiptap/extension-highlight'
import { TextStyle } from '@tiptap/extension-text-style'
import { Color } from '@tiptap/extension-color'
// Custom extensions
import { UiState } from '@/components/tiptap-extension/ui-state-extension'
import { NodeBackground } from '@/components/tiptap-extension/node-background-extension'
// UI components
import { DragContextMenu } from '@/components/tiptap-ui/drag-context-menu'
// Editor styles
import '@/components/tiptap-node/paragraph-node/paragraph-node.scss'
import '@/components/tiptap-node/blockquote-node/blockquote-node.scss'
import '@/components/tiptap-node/code-block-node/code-block-node.scss'
import '@/components/tiptap-node/heading-node/heading-node.scss'
import '@/components/tiptap-node/horizontal-rule-node/horizontal-rule-node.scss'
import '@/components/tiptap-node/list-node/list-node.scss'
// Global styles
import '@/styles/_keyframe-animations.scss'
import '@/styles/_variables.scss'
export default function TiptapEditor() {
const editor = useEditor({
immediatelyRender: false,
extensions: [
// Base extensions
StarterKit,
// Text styling extensions which handle the "Colors" menu
TextStyle,
Highlight,
Color,
NodeBackground,
// UI state management (REQUIRED for drag context menu)
// This was installed automatically by the CLI
UiState,
],
content: `
<h1>Welcome to Tiptap</h1>
<p>Hover over any block to see the drag handle appear on the left.</p>
<blockquote>
<p>Click the drag handle to access the context menu.</p>
</blockquote>
`,
})
return (
<EditorContext.Provider value={{ editor }}>
<EditorContent editor={editor} />
<DragContextMenu />
</EditorContext.Provider>
)
}You should be able to see the drag handle on hover and open the context menu by clicking it.
Extension Explanation
| Extension | Purpose | Required? |
|---|---|---|
StarterKit | Provides basic editing features (paragraphs, headings, lists, etc.) | Yes |
Highlight | Enables text highlighting with colors | Optional |
TextStyle + Color | Enables text color changes | Optional |
NodeBackground | Enables background color changes for blocks | Optional |
UiState | Manages UI state for drag operations | Yes |
These extensions are optional but enable specific features in the context menu. Without them, those features will be automatically hidden.
Props Reference
| Prop | Type | Default | Description |
|---|---|---|---|
editor | Editor | null | Required (unless using EditorContext) | Your Tiptap editor instance |
withSlashCommandTrigger | boolean | true | Shows a slash command button alongside the drag handle |
mobileBreakpoint | number | 768 | Screen width (in px) below which the drag handle is hidden |
Note: The
editorprop is required unless you are usingEditorContext(or a similar context provider) to supply the editor instance. If the context is available, you can omit theeditorprop.
Advanced Customization
Disabling Slash Command Trigger
If you don't want the slash command button:
<DragContextMenu editor={editor} withSlashCommandTrigger={false} />Custom Mobile Breakpoint
Adjust when the drag handle hides on smaller screens:
<DragContextMenu
editor={editor}
mobileBreakpoint={1024} // Hide on tablets too
/>Programmatic Control
You can programmatically control drag handle behavior through editor commands:
// Lock drag handle (prevent hiding)
editor.commands.setLockDragHandle(true)
// Hide drag handle
editor.commands.setMeta('hideDragHandle', true)
// Set dragging state
editor.commands.setIsDragging(true)Feature Reference
Available Context Menu Actions
The context menu dynamically shows actions based on:
- Current node type
- Available extensions
- Editor selection
- Content state
Color Actions
- Text Color: Change text color (requires
TextStyle+Colorextensions) - Highlight: Apply background highlights (requires
Highlightextension)
Transform Actions
Transform the current block into:
- Paragraph
- Heading 1, 2, 3
- Bullet List
- Numbered List
- Task List (requires
TaskList+TaskItemextensions) - Blockquote
- Code Block
Core Actions
- Copy: Copy block content to clipboard
- Duplicate: Create a copy of the current block
- Copy Anchor Link: Copy a link to the current block (requires ID support)
Format Actions
- Reset Formatting: Remove all formatting marks
Image Actions (for image nodes)
- Download: Download the image (requires
Imageextension)
Delete Actions
- Delete: Remove the current block
Keyboard Shortcuts
The context menu respects standard Tiptap keyboard shortcuts:
- Command/Ctrl + D: Duplicate block
- Command/Ctrl + Shift + C: Copy to clipboard
- Command/Ctrl + Delete/Backspace: Delete block
Next Steps
After integrating the DragContextMenu, you might want to:
- Add More Extensions: Explore other Tiptap extensions to enhance functionality
- Customize Styling: Adjust colors, spacing, and animations to match your brand
- Add Slash Commands: Integrate the SlashDropdownMenu component for quick insertions
- Enable AI Features: Set up AI integration for the "Ask AI" context menu option
- Add Collaboration: Use Tiptap Collaboration for real-time editing