探索 Tiptap V3 的最新功能

安装协作

本指南将帮助您开始在 Tiptap 编辑器中进行协作编辑。如果您已经在使用 Tiptap 编辑器,可以直接跳到 准备您的编辑器 部分。

安装 Tiptap 编辑器

如果尚未安装 Tiptap 编辑器,请在 CLI 中运行以下命令以安装此示例所需的基本编辑器和扩展:

npm install @tiptap/extension-document @tiptap/extension-paragraph @tiptap/extension-text @tiptap/react

安装完成后,您可以使用以下基本设置启动 Tiptap 编辑器。只需将以下代码片段添加到您的项目中:

准备您的编辑器

要在您的 Tiptap 编辑器中引入团队协作功能,请将 Yjs 库和编辑器协作扩展集成到您的前端中。此设置使用 Y.Doc,一个共享文档模型,而不仅仅是处理纯文本。 之后,我们将 Y.Doc 连接到 TiptapCollabProvider 以同步用户交互。

集成 Yjs 和协作扩展

将编辑器协作扩展和 Yjs 库添加到您的前端:

npm install @tiptap/extension-collaboration @tiptap/y-tiptap yjs y-protocols

接下来,更新您的 index.jsx 以包含这些新导入:

import './styles.scss'

import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import React from 'react'

import Collaboration from '@tiptap/extension-collaboration'
import * as Y from 'yjs'

const doc = new Y.Doc() // 为共享编辑初始化 Y.Doc

export default () => {
  const editor = useEditor({
    extensions: [
      Document,
      Paragraph,
      Text,
      Collaboration.configure({
        document: doc, // 为协作配置 Y.Doc
      }),
    ],
    content: `
      <p>
        这是 Tiptap 的一个极简版本。它支持文档、段落和文本。就这些。这对真正的极简主义者来说可能太多了。
      </p>
      <p>
        段落扩展不是必需的,但您至少需要一个节点。当然,那个节点可以是其他东西。
      </p>
    `,
  })

  return <EditorContent editor={editor} />
}

您的编辑器现在几乎准备好进行协作编辑了!

启动您的文档服务器

  1. 激活计划: 开始一个 免费试用或选择一个订阅
  2. 添加环境。 在您的 仪表板 上,点击 添加环境 按钮,输入名称并选择最接近用户的区域。
  3. 检查配置。 一旦保存环境,您的应用程序将启动。访问 配置页面 复制您的 AppID、API 密钥和其他连接详细信息。

连接到您的文档服务器

为了实现协作功能,安装 @tiptap-cloud/provider 包:

设置私有注册表

请注意,您需要按照这里的说明设置对私有注册表的访问。

此外,您可能需要将以下行添加到您的 .npmrc 中:

@tiptap-cloud:registry=https://registry.tiptap.dev/
npm install @tiptap-cloud/provider

接下来,在您的 index.jsx 文件中配置提供者,并输入您的服务器详细信息:

  • name:作为同步的文档标识符。
  • appID:在您启动应用后,可以在您的 云账户 中找到。对于本地部署,使用 baseUrl 替换 appID
  • token:在测试时使用您在 云界面 中获取的 JWT,但在生产环境中生成您自己的 JWT。

添加初始内容

在非协作设置中集成编辑器时,使用此处显示的方法来设置内容是完全可以接受的。然而,如果您转到协作环境,则需要修改添加初始内容的方式,如下一标题所示。

添加以下代码以完成设置:

import './styles.scss'

import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import React from 'react'

import Collaboration from '@tiptap/extension-collaboration'
import * as Y from 'yjs'

// 导入提供者和 useEffect
import { useEffect } from 'react'
import { TiptapCollabProvider } from '@tiptap-cloud/provider'

const doc = new Y.Doc()

export default () => {
  const editor = useEditor({
    extensions: [
      Document,
      Paragraph,
      Text,
      Collaboration.configure({
        document: doc,
      }),
    ],
    content: `
      <p>
        这是 Tiptap 的一个极简版本。它支持文档、段落和文本。就这些。这对真正的极简主义者来说可能太多了。
      </p>
      <p>
        段落扩展不是必需的,但您至少需要一个节点。当然,那个节点可以是其他东西。
      </p>
    `,
  })

  // 连接到您的协作服务器
  useEffect(() => {
    const provider = new TiptapCollabProvider({
      name: 'document.name', // 用于同步的唯一文档标识符。这是您的文档名称。
      appId: '7j9y6m10', // 您云仪表板的 AppID 或本地部署的 `baseURL`
      token: 'notoken', // 您的 JWT 令牌
      document: doc,
    })
  }, [])

  return <EditorContent editor={editor} />
}

完成这些步骤后,您应该能够在两个不同的浏览器中打开并通过独立的 WebSocket 连接同时连接到同一文档。

为了清晰测试协作功能,推荐使用两个不同的浏览器来保证唯一的 websocket 连接。

正确初始化内容

在您的 Tiptap 编辑器中实现协作时,您可能会注意到,每次编辑器加载时,初始内容都会重复添加。为了防止这种情况,使用 .setContent() 方法仅单次设置初始内容。

import './styles.scss'

import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import React from 'react'

import * as Y from 'yjs'
import Collaboration from '@tiptap/extension-collaboration'
import { useEffect } from 'react'

import { TiptapCollabProvider } from '@tiptap-cloud/provider'

const doc = new Y.Doc()

export default () => {
  const editor = useEditor({
    extensions: [
      Document,
      Paragraph,
      Text,
      Collaboration.configure({
        document: doc,
      }),
    ],
    // 在编辑器初始化时移除自动添加内容。
  })

  useEffect(() => {
    const provider = new TiptapCollabProvider({
      name: 'document.name', // 用于同步的唯一文档标识符。这是您的文档名称。
      appId: '7j9y6m10', // 您云仪表板的 AppID 或本地部署的 `baseURL`
      token: 'notoken', // 您的 JWT 令牌
      document: doc,

      // onSynced 回调确保初始内容仅设置一次,使用 editor.setContent(),防止在编辑器同步时重复加载内容。
      onSynced() {
        if (!doc.getMap('config').get('initialContentLoaded') && editor) {
          doc.getMap('config').set('initialContentLoaded', true)

          editor.commands.setContent(`
          <p>这是 Tiptap 的一个极简版本。它支持文档、段落和文本。就这些。这对真正的极简主义者来说可能太多了。</p>
          <p>段落扩展不是必需的,但您至少需要一个节点。当然,那个节点可以是其他东西。</p>
          `)
        }
      },
    })
  }, [])

  return <EditorContent editor={editor} />
}

这确保初始内容仅设置一次。要测试新的初始内容,请通过更改 name 参数(例如,从 document.name 更改为 document.name2)创建新文档。

禁用默认撤销/重做

如果您正在将协作集成到本演示中提供的编辑器以外的编辑器中,您可能需要禁用编辑器的默认撤销/重做功能。这是为了避免与协作历史管理发生冲突:您不希望撤销其他人的更改。

只有当您的项目包含 Tiptap 的 StarterKitUndo/Redo 扩展时,才需要此操作。

const editor = useEditor({
  extensions: [
    StarterKit.configure({
      undoRedo: false, // 禁用默认的撤销/重做扩展,以使用协作的历史记录管理功能
    }),
  ],
})

遵循本指南将设置一个基本而又功能齐全的协作 Tiptap 编辑器,通过协作云或本地后端进行同步。

认证用户

了解如何使用 JSON Web Tokens (JWT) 保护您的协作 Tiptap 编辑器。下一篇指南提供了逐步说明,教您如何创建和管理 JWT,以便在测试和生产中确保受控访问,并提供详细示例。阅读更多关于 认证 的信息。