mcpField
T
tiptap

tiptap

github.com/jezweb开发1.1k478 次安装3 周前更新
代码仓库

关于 tiptap

tiptap 是一项指导开发者使用 Tiptap 构建 React 富文本编辑器的技能,提供初始化方式、扩展配置、模板,以及常见集成与性能问题的处理建议。

主要功能

  1. 01React 编辑器初始化指南
  2. 02扩展配置模式
  3. 03图片上传模板
  4. 04使用 Y.js 协同编辑
  5. 05Markdown 与表单集成
  6. 06SSR 和性能问题排查

适用场景

  1. 01在 React 中搭建 Tiptap 编辑器
  2. 02为编辑器内容添加图片上传
  3. 03配置协同编辑
  4. 04排查 SSR 或编辑器性能问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jezweb/claude-skills --skill tiptap

安装后在 Claude Code 中输入/tiptap确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.claude-plugin/
plugin.json
references/
common-errors.md
extension-catalog.md
tiptap-docs.md
rules/
tiptap.md
templates/
base-editor.tsx
common-extensions.ts
image-upload-r2.tsx
minimal-tiptap-setup.sh
package.json
tiptap-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 immediatelyRender explicitly to false”
  • 这是 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 - 图片缩放功能

官方文档


软件包版本(已于 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 错误
  • 生产构建成功

有疑问?遇到问题?

  1. 查看 references/common-errors.md 以排查问题
  2. 确认已设置 immediatelyRender: false
  3. 查看官方文档:https://tiptap.dev
  4. 确保已安装 @tiptap/pm 对等依赖

评论

支持 Markdown