关于 tiptap
tiptap 是一项指导开发者使用 Tiptap 构建 React 富文本编辑器的技能,提供初始化方式、扩展配置、模板,以及常见集成与性能问题的处理建议。
主要功能
- 01React 编辑器初始化指南
- 02扩展配置模式
- 03图片上传模板
- 04使用 Y.js 协同编辑
- 05Markdown 与表单集成
- 06SSR 和性能问题排查
适用场景
- 01在 React 中搭建 Tiptap 编辑器
- 02为编辑器内容添加图片上传
- 03配置协同编辑
- 04排查 SSR 或编辑器性能问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jezweb/ claude-skills --skill tiptap安装后在 Claude Code 中输入/tiptap确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.md.claude-plugin/plugin.jsonreferences/common-errors.mdextension-catalog.mdtiptap-docs.mdrules/tiptap.mdtemplates/base-editor.tsxcommon-extensions.tsimage-upload-r2.tsxminimal-tiptap-setup.shpackage.jsontiptap-prose.css详细介绍
Tiptap 富文本编辑器
状态:生产就绪 最后更新:2026-01-21 依赖项:React 19+、Tailwind v4、shadcn/ui(推荐) 最新版本:@tiptap/[email protected]、@tiptap/[email protected]、@tiptap/[email protected](已于 2026-01-21 验证)
快速开始(5 分钟)
1. 安装依赖项
npm install @tiptap/react @tiptap/starter-kit @tiptap/pm @tiptap/extension-image @tiptap/extension-color @tiptap/extension-text-style @tiptap/extension-typography
为什么这很重要:
@tiptap/pm是必需的对等依赖项(ProseMirror 引擎)- StarterKit 包含 20 多个核心扩展(标题、列表、粗体、斜体等)
- 图片、颜色和排版是 StarterKit 中未包含的常用扩展
重要提示:如果使用 Tiptap v3.14.0+,拖动手柄功能要求最低版本为 v3.14.0(该版本已修复回归问题)。对于带拖动手柄的 Pro 扩展,由于依赖 tippyjs-react,建议使用 React 18。
2. 创建 SSR 安全的编辑器
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
export function Editor() {
const editor = useEditor({
extensions: [StarterKit],
content: '<p>Hello World!</p>',
immediatelyRender: false, // ⚠️ CRITICAL for SSR/Next.js
editorProps: {
attributes: {
class: 'prose prose-sm focus:outline-none min-h-[200px] p-4',
},
},
})
return <EditorContent editor={editor} />
}
重要:
- 对 Next.js/SSR 应用,始终设置
immediatelyRender: false(可避免 hydration 不匹配) - 如果不这样做,你会看到:“SSR has been detected, please set
immediatelyRenderexplicitly tofalse” - 这是 Tiptap 用户报告最多的错误
3. 添加 Tailwind Typography(可选,但推荐)
npm install @tailwindcss/typography
更新你的 tailwind.config.ts:
import typography from '@tailwindcss/typography'
export default {
plugins: [typography],
}
为什么这很重要:
- 为标题、列表、链接等提供默认的 prose 样式
- 没有它,格式化后的内容看起来会缺少样式
- 替代方案:使用带有
.tiptap选择器的自定义 Tailwind 类
三步设置流程
第 1 步:选择集成方式
选项 A:shadcn Minimal Tiptap 组件(推荐)
安装预构建的 shadcn 组件:
npx shadcn@latest add https://raw.githubusercontent.com/Aslam97/shadcn-minimal-tiptap/main/registry/block-registry.json
此操作会安装:
- 功能齐全的编辑器组件,带工具栏
- 图片上传支持
- 带语法高亮的代码块
- 已配置的 Typography 扩展
- 深色模式支持
选项 B:构建自定义编辑器(完全掌控)
使用此技能中的模板:
templates/base-editor.tsx- 最简编辑器设置templates/common-extensions.ts- 扩展集合templates/tiptap-prose.css- Tailwind 样式
要点:
- 选项 A:设置更快,UI 具有预设风格
- 选项 B:完全自定义,采用无头方式
- 两种方式都适用于 React + Tailwind v4
第 2 步:配置扩展
扩展可为编辑器添加功能:
import StarterKit from '@tiptap/starter-kit'
import Image from '@tiptap/extension-image'
import Link from '@tiptap/extension-link'
import Typography from '@tiptap/extension-typography'
const editor = useEditor({
extensions: [
StarterKit.configure({
// Customize built-in extensions
heading: {
levels: [1, 2, 3],
},
bulletList: {
keepMarks: true,
},
}),
Image.configure({
inline: true,
allowBase64: false, // ⚠️ Prevent base64 bloat
resize: {
enabled: true,
directions: ['top-right', 'bottom-right', 'bottom-left', 'top-left'],
minWidth: 100,
minHeight: 100,
alwaysPreserveAspectRatio: true,
},
}),
Link.configure({
openOnClick: false,
HTMLAttributes: {
class: 'text-primary underline',
},
}),
Typography, // Smart quotes, dashes, etc.
],
})
重要:
- 将
allowBase64: false设为 false,以避免产生过大的 JSON 负载 - 使用上传处理程序模式(参见 templates/image-upload-r2.tsx)
- 扩展顺序很重要——必须先加载依赖项
第 3 步:处理图片上传(如有需要)
模式:Base64 预览 → 后台上传 → 替换为 URL
完整实现请参见 templates/image-upload-r2.tsx:
import { Editor } from '@tiptap/core'
async function uploadImageToR2(file: File, env: Env): Promise<string> {
// 1. Create base64 preview for immediate display
const reader = new FileReader()
const base64 = await new Promise<string>((resolve) => {
reader.onload = () => resolve(reader.result as string)
reader.readAsDataURL(file)
})
// 2. Insert preview into editor
editor.chain().focus().setImage({ src: base64 }).run()
// 3. Upload to R2 in background
const formData = new FormData()
formData.append('file', file)
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
})
const { url } = await response.json()
// 4. Replace base64 with permanent URL
editor.chain()
.focus()
.updateAttributes('image', { src: url })
.run()
return url
}
此模式的优点:
- 立即向用户反馈(预览)
- 不会因 Base64 导致数据库膨胀
- 适用于 Cloudflare R2
- 能妥善处理错误
关键规则
务必执行
✅ 对 SSR 应用,在 useEditor() 中设置 immediatelyRender: false
✅ 安装 @tailwindcss/typography,以实现 prose 样式
✅ 使用上传处理程序上传图片(不要使用 Base64)
✅ 对编辑器配置进行记忆化,避免重新渲染
✅ 包含对等依赖项 @tiptap/pm
切勿执行
❌ 在 Next.js/SSR 中使用 immediatelyRender: true(默认值)
❌ 在数据库中将图片存储为 Base64(上传后使用 URL)
❌ 忘记为编辑器容器添加 prose 类
❌ 在协作模式下加载超过 100 个 widget
❌ 使用 Create React App(与 v3 不兼容——请使用 Vite)
避免已知问题
此技能可避免 7 个已记录的问题:
问题 #1:SSR Hydration 不匹配
错误:“SSR has been detected, please set immediatelyRender explicitly to false”
来源:GitHub Issue #5856、#5602
原因:默认的 immediatelyRender: true 会破坏 Next.js hydration
预防措施:模板默认包含 immediatelyRender: false
问题 #2:编辑器每次按键都会重新渲染
错误:输入卡顿,大型文档性能不佳
来源:Tiptap 性能文档
发生原因:useEditor() hook 会在每次发生更改时重新渲染组件
预防措施:使用 useEditorState() hook 或记忆化模式(参见模板)
问题 #3:Tailwind Typography 无法使用
错误:标题/列表未应用样式,看不到任何格式
来源:shadcn Tiptap 讨论
发生原因:缺少 @tailwindcss/typography 插件
预防措施:技能的检查清单中包含 Typography 插件安装步骤
问题 #4:图片上传导致 Base64 内容膨胀
错误:JSON 负载膨胀到数 MB,保存速度变慢,数据库膨胀 来源:Tiptap 图片文档 发生原因:默认允许使用 Base64,且未配置上传处理程序 预防措施:提供带 URL 替换模式的 R2 上传模板
问题 #5:Create React App 中的构建错误
错误:升级到 v3 后出现 “jsx-runtime” 模块解析错误 来源:GitHub 问题 #6812 发生原因:CRA 与 v3 的模块结构不兼容 预防措施:技能文档将 Vite 列为首选打包工具,并提供可运行的配置
问题 #6:ProseMirror 多个版本冲突
错误:Error: Looks like multiple versions of prosemirror-model were loaded
来源:GitHub 问题 #577(131 条评论)、问题 #6171
发生原因:安装额外的 Tiptap 扩展可能会引入不同版本的 prosemirror-model 或 prosemirror-view,导致 node_modules 中出现重复依赖。在测试环境中,unique-id 扩展尤其容易引发问题。
预防措施:使用软件包解析配置,强制使用单一版本的 ProseMirror
// package.json
{
"resolutions": {
"prosemirror-model": "~1.21.0",
"prosemirror-view": "~1.33.0",
"prosemirror-state": "~1.4.3"
}
}
或者重新安装依赖:
rm -rf node_modules package-lock.json
npm install
注意:@tiptap/pm 软件包旨在避免此问题,但扩展仍可能引入冲突。
问题 #7:EditorProvider 与 useEditor 混淆(来源于社区)
错误:SSR has been detected, please set 'immediatelyRender' explicitly to 'false'(两者同时使用时)
来源:GitHub 问题 #5856 评论
发生原因:用户常常会同时使用 EditorProvider 和 useEditor,但 EditorProvider 是用于设置 React Context 的 useEditor 包装器,因此不应同时使用两者。
预防措施:只选择一种模式
错误模式:
// Don't use both together
<EditorProvider>
<MyComponent />
</EditorProvider>
function MyComponent() {
const editor = useEditor({ ... }) // ❌ Wrong - EditorProvider already created editor
}
正确模式:
// Option 1: Use EditorProvider only
<EditorProvider immediatelyRender={false} extensions={[StarterKit]}>
<EditorContent />
</EditorProvider>
// Option 2: Use useEditor only
function Editor() {
const editor = useEditor({
extensions: [StarterKit],
immediatelyRender: false,
})
return <EditorContent editor={editor} />
}
配置文件参考
Tailwind Prose 样式(tiptap-prose.css)
/* Apply to editor container */
.tiptap {
/* Tailwind Typography */
@apply prose prose-sm sm:prose-base lg:prose-lg dark:prose-invert max-w-none;
/* Custom overrides */
h1 {
@apply text-3xl font-bold mt-8 mb-4;
}
h2 {
@apply text-2xl font-semibold mt-6 mb-3;
}
p {
@apply my-4 text-base leading-7;
}
ul, ol {
@apply my-4 ml-6;
}
code {
@apply bg-muted px-1.5 py-0.5 rounded text-sm font-mono;
}
pre {
@apply bg-muted p-4 rounded-lg overflow-x-auto;
}
blockquote {
@apply border-l-4 border-primary pl-4 italic my-4;
}
}
这些设置的作用:
prose类提供一致的格式dark:prose-invert自动处理深色模式- 自定义覆盖使用语义化的 Tailwind v4 颜色
常见模式
模式 1:使用 Y.js 协同编辑
import { useEditor } from '@tiptap/react'
import Collaboration from '@tiptap/extension-collaboration'
import * as Y from 'yjs'
const ydoc = new Y.Doc()
const editor = useEditor({
extensions: [
StarterKit.configure({
history: false, // Disable history for collaboration
}),
Collaboration.configure({
document: ydoc,
}),
],
})
适用场景:实时多人编辑(类似 Notion)
参见:templates/collaborative-setup.tsx 查看完整示例
模式 2:Markdown 支持
import { useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { Markdown } from '@tiptap/markdown'
// Load editor with markdown content
const editor = useEditor({
extensions: [StarterKit, Markdown],
content: '# Hello World\n\nThis is **Markdown**!',
contentType: 'markdown', // ⚠️ CRITICAL: Must specify or content parsed as HTML
immediatelyRender: false,
})
// Get markdown from editor
const markdownOutput = editor.getMarkdown()
// Insert markdown content
editor.commands.setContent('## New heading', { contentType: 'markdown' })
editor.commands.insertContent('**Bold** text', { contentType: 'markdown' })
适用场景:以 Markdown 格式存储内容,显示/编辑富文本
安装:npm install @tiptap/[email protected]
状态:Beta(于 2025 年 10 月发布,API 稳定但可能会有更改)
重要:设置 Markdown 内容时,始终指定 contentType: 'markdown'
近期修复(v3.15.0-v3.16.0):
- 修复下划线与粗体/斜体混合且格式范围未完全重叠时 Markdown 输出不正确的问题
- 改进重叠格式标记的序列化
- 来源:v3.16.0 发布说明
模式 3:与 react-hook-form 集成
import { useForm, Controller } from 'react-hook-form'
function BlogForm() {
const { control, handleSubmit } = useForm()
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="content"
control={control}
render={({ field }) => (
<Editor
content={field.value}
onUpdate={({ editor }) => {
field.onChange(editor.getHTML())
}}
/>
)}
/>
</form>
)
}
适用场景:博客文章、评论以及任何基于表单的内容
使用捆绑资源
脚本(scripts/)
此技能没有可执行脚本。
模板(templates/)
所有项目必需:
templates/base-editor.tsx- 最简 React 编辑器组件templates/package.json- 必需依赖项
根据需求选用:
templates/minimal-tiptap-setup.sh- 安装 shadcn 组件templates/image-upload-r2.tsx- R2 上传处理程序templates/tiptap-prose.css- Tailwind 样式templates/collaborative-setup.tsx- Y.js 协作templates/common-extensions.ts- 扩展包
何时加载这些模板:用户要求以下操作时,Claude 应参考模板:
- 设置 tiptap 编辑器
- 添加图片上传
- 配置协作编辑
- 使用 Tailwind prose 设置样式
参考资料(references/)
references/tiptap-docs.md- 重要文档链接references/common-errors.md- 错误排查指南references/extension-catalog.md- 常用扩展列表
Claude 应何时加载这些资料:排查错误、探索扩展、了解 API
高级主题
自定义扩展
创建自己的 Tiptap 扩展:
import { Node } from '@tiptap/core'
const CustomNode = Node.create({
name: 'customNode',
group: 'block',
content: 'inline*',
parseHTML() {
return [{ tag: 'div[data-custom]' }]
},
renderHTML({ HTMLAttributes }) {
return ['div', { 'data-custom': '', ...HTMLAttributes }, 0]
},
addCommands() {
return {
insertCustomNode: () => ({ commands }) => {
return commands.insertContent({ type: this.name })
},
}
},
})
适用场景:自定义组件、嵌入内容、交互元素
斜杠命令
添加类似 Notion 的 / 命令:
import { Extension } from '@tiptap/core'
import Suggestion from '@tiptap/suggestion'
const SlashCommands = Extension.create({
name: 'slashCommands',
addOptions() {
return {
suggestion: {
char: '/',
items: ({ query }) => {
return [
{ title: 'Heading 1', command: ({ editor, range }) => {
editor.chain().focus().deleteRange(range).setHeading({ level: 1 }).run()
}},
{ title: 'Bullet List', command: ({ editor, range }) => {
editor.chain().focus().deleteRange(range).toggleBulletList().run()
}},
]
},
},
}
},
addProseMirrorPlugins() {
return [Suggestion({ editor: this.editor, ...this.options.suggestion })]
},
})
适用场景:提升效率的快捷操作、快速格式设置
依赖项
必需:
@tiptap/react@^3.16.0- React 集成(支持 React 19)@tiptap/starter-kit@^3.16.0- 基础扩展包@tiptap/pm@^3.16.0- ProseMirror 同级依赖项react@^19.0.0- React 框架
React 版本兼容性:
- Tiptap 核心:从 v2.10.0 起支持 React 19
- UI 组件:搭配 React 18 效果最佳(官方文档推荐使用 Next.js 15)
- Pro 扩展:可能需要 React 18 - 拖动手柄扩展依赖已归档的 tippyjs-react,且不支持 React 19(Issue #5876)
可选:
@tiptap/extension-audio@^3.16.0- 音频支持(v3.16.0 新增)@tiptap/extension-image@^3.16.0- 图片支持@tiptap/extension-link@^3.16.0- 链接支持(v3 新增,已包含在 StarterKit 中)@tiptap/extension-color@^3.16.0- 文本颜色@tiptap/extension-typography@^3.16.0- 智能排版@tiptap/extension-collaboration@^3.16.0- 实时协作@tiptap/extension-markdown@^3.16.0- Markdown 支持(Beta)@tailwindcss/typography@^0.5.19- 正文样式yjs@^13.6.0- 协作编辑后端react-medium-image-zoom@^5.2.0- 图片缩放功能
官方文档
- Tiptap:https://tiptap.dev
- 安装指南:https://tiptap.dev/docs/editor/installation/react
- 扩展:https://tiptap.dev/docs/editor/extensions
- API 参考:https://tiptap.dev/docs/editor/api/editor
- shadcn minimal-tiptap:https://github.com/Aslam97/shadcn-minimal-tiptap
- Context7 库 ID:tiptap/tiptap
软件包版本(已于 2026-01-21 验证)
{
"dependencies": {
"@tiptap/react": "^3.16.0",
"@tiptap/starter-kit": "^3.16.0",
"@tiptap/pm": "^3.16.0",
"@tiptap/extension-audio": "^3.16.0",
"@tiptap/extension-image": "^3.16.0",
"@tiptap/extension-color": "^3.16.0",
"@tiptap/extension-text-style": "^3.16.0",
"@tiptap/extension-typography": "^3.16.0",
"@tiptap/extension-link": "^3.16.0",
"@tiptap/extension-markdown": "^3.16.0"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.19",
"react": "^19.2.3",
"react-dom": "^19.2.3"
}
}
生产环境示例
此技能基于真实项目实现:
- GitLab:使用 Tiptap 编写议题/MR 描述
- Statamic CMS:将 Tiptap 作为默认富文本编辑器
- shadcn minimal-tiptap:每周下载量 3.14M
节省 Token:约 71%(14k → 4k tokens) 避免的错误:7/7 个已记录错误(5 个关键设置错误 + 2 个社区实践) 验证情况:✅ SSR 兼容性,✅ 图片上传,✅ Tailwind v4,✅ 性能,✅ React 19 兼容性
故障排查
问题:"SSR has been detected, please set immediatelyRender explicitly to false"
解决方案:在 useEditor() 配置中添加 immediatelyRender: false
问题:标题/列表看起来没有样式
解决方案:安装 @tailwindcss/typography,并为编辑器容器添加 prose 类
问题:输入时编辑器卡顿
解决方案:对于只读渲染,使用 useEditorState() hook 代替 useEditor(),或对编辑器配置进行记忆化处理
问题:图片导致 JSON 过大
解决方案:在 Image 扩展配置中设置 allowBase64: false,并使用上传处理程序(参见 templates/image-upload-r2.tsx)
问题:在 Create React App 中构建失败
解决方案:切换到 Vite——CRA 与 Tiptap v3 不兼容。有关 Vite 设置,请参见 cloudflare-worker-base skill。
完整设置清单
使用此清单验证设置:
- 已安装
@tiptap/react、@tiptap/starter-kit、@tiptap/pm - 在
useEditor()配置中设置了immediatelyRender: false - 已安装
@tailwindcss/typography插件 - 已为编辑器容器添加
prose类 - 已配置图片上传处理程序(如果使用图片)
- 在 Image 扩展中设置了
allowBase64: false - 编辑器渲染时没有 hydration 错误
- 格式化文本显示正确(标题、列表等)
- 开发服务器运行时没有 TypeScript 错误
- 生产构建成功
有疑问?遇到问题?
- 查看
references/common-errors.md以排查问题 - 确认已设置
immediatelyRender: false - 查看官方文档:https://tiptap.dev
- 确保已安装
@tiptap/pm对等依赖