A modern, extensible rich-text editor built with Next.js 15, TypeScript, and TipTap v3 — featuring a modular menu bar, bubble menus, image resizing, YouTube embeds, table tools, and customizable extensions for documents, blog content, and comments.
-
🧩 Extension-based setup
- Supports
document,content,comment, anddefaulteditor modes - Modular extension configuration via
/constants/EditorExtension.ts
- Supports
-
🧰 Dynamic Menu Bar
- Fully dynamic toolbar defined in
/constants/EditorMenuOptions.ts - Includes dropdowns, modals, input fields, and grouped button sets
- Fully dynamic toolbar defined in
-
💬 Smart Bubble Menus
-
Context-aware popups for:
- Text (bold, italic, underline, links)
- Images (resize, align, delete)
- Tables (insert, merge, align)
- Embeds (YouTube, custom components)
-
-
🖼️ Image Resize + Alignment
- Custom node view: resize, align, and delete images interactively
-
🎬 Embeds
- YouTube and iframe embeds with editable parameters
-
🪄 Details Block
- Expandable “Details” element similar to Markdown
<details>/<summary>
- Expandable “Details” element similar to Markdown
-
🧷 Editor Context API
- Centralized editor instance management with real-time content tracking
-
💾 Import / Export
- Easily serialize and restore editor state as HTML or JSON
-
⚙️ Built with:
- Next.js 15 (App Router)
- TypeScript
- Tailwind CSS + shadcn/ui
- TipTap v3
- Lucide Icons
.
└── simple-tiptap-editor/
├── app/
│ ├── content/page.tsx
│ ├── docs/page.tsx
│ ├── comment/page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── components/
│ ├── bubbleMenu # stores bubble menu
│ ├── extensions # stoes extensions
│ ├── models # Editor popup modals/
│ │ ├── image.tsx
│ │ └── ...
│ ├── ui # shadcn components
│ ├── EditorButton.tsx
│ ├── EditorMenuBar.tsx
│ ├── EditorPage.tsx
│ ├── MenuButton.tsx
│ └── MenuSelect.tsx
├── constants/
│ ├── EditorMenuOptions.ts
│ ├── EditorExtensions.tsx
│ └── EditorStateOptions.tsx
├── context/
│ └── EditorContext.tsx
├── lib/
│ └── utils.ts
├── ReadMe.md
├── package.json
└── ...
git clone https://github.com/coderooz/Simple-Tiptap-editor.git
cd simple-tiptap-editor
npm installnpm run devOpen → http://localhost:3000
npm run build
npm start| Mode | Description | Uses Extensions |
|---|---|---|
comment |
Minimal editor for comments | COMMENT_EXTENSIONS |
document |
Full-page editor for documents | DOCUMENT_EXTENSIONS |
content |
Blog or post-style rich editor | BLOG_EXTENSIONS |
default |
Basic TipTap setup | DEFAULT_EXTENSIONS |
Switch using:
const { setEditorType } = useEditorContext();
setEditorType("document");Use the global context to access or modify the editor:
import { useEditorContext } from "@/context/EditorContext";
const { editor, editorType, setEditorType, editorContent, setEditorContent } =
useEditorContext();You can modify toolbar buttons via
/constants/EditorMenuOptions.ts:
{
title: "Bold",
icon: Bold,
group: "text",
type: "button",
isActive: (editor) => editor.isActive("bold"),
action: (editor) => editor.chain().focus().toggleBold().run(),
}Supports:
buttondropdowninputmodel(for modals/dialogs)
All TipTap or custom extensions are registered in
/constants/EditorExtension.ts:
import { Extension } from "@tiptap/core";
export const MyExtension = Extension.create({
name: "myExtension",
addKeyboardShortcuts() {
return {
"Mod-b": () => this.editor.commands.toggleBold(),
};
},
});Then add it:
DEFAULT_EXTENSIONS.push(MyExtension);const html = editor.getHTML();editor.commands.setContent(html);const json = editor.getJSON();editor.commands.setContent(json);- Use Developer Mode or Admin privileges on Windows to fix symlink issues with Vercel builds.
- Use
useEditorContext()to ensure reactive state when switching editor types. - Use BubbleMenus for contextual controls — e.g., resize images, format text, etc.
Build and deploy to Vercel or any Next.js-compatible platform:
vercel build
vercel deployRanit Saha (Coderooz) 📍 Barpeta Road, Assam, India 🌐 https://www.coderooz.xyz ✉️ coderooz.dev@gmail.com
MIT License © 2025 Coderooz
