tiptap/docs/collaboration/install.md

233 lines
7.8 KiB
Markdown
Raw Normal View History

2024-03-09 21:53:59 +08:00
---
tableOfContents: true
---
# Install Collaboration
2024-03-09 21:52:46 +08:00
This guide will get you started with collaborative editing in the Tiptap Editor. If you're already using Tiptap Editor, feel free to skip ahead to the "Adding Collaboration" section.
2024-03-09 21:52:46 +08:00
### Installing Tiptap Editor
2024-03-09 21:52:46 +08:00
If Tiptap Editor isn't installed yet, run the following command in your CLI for either React or Vue to install the basic editor and necessary extensions for this example:
```bash
npm install @tiptap/extension-document @tiptap/extension-paragraph @tiptap/extension-text @tiptap/react
```
2024-03-09 21:52:46 +08:00
Once installed, you can get your Tiptap Editor up and running with this basic setup. Just add the following code snippets to your project:
https://embed.tiptap.dev/preview/Examples/Minimal
2024-03-09 21:52:46 +08:00
## Adding Collaboration
2024-03-09 21:52:46 +08:00
To introduce team collaboration features into your Tiptap Editor, integrate the Yjs library and Editor Collaboration extension into your frontend. This setup uses Y.Doc, a shared document model, rather than just handling plain text.
Afterwards we will connect Y.Doc to the TiptapCollabProvider to synchronize user interactions.
2024-03-09 21:52:46 +08:00
### Integrating Yjs and the Collaboration Extension
2024-03-09 21:52:46 +08:00
Add the Editor Collaboration extension and Yjs library to your frontend:
```bash
npm install @tiptap/extension-collaboration yjs
```
2024-03-09 21:52:46 +08:00
Then, update your index.jsx to include these new imports:
```typescript
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'
export default () => {
2024-03-09 21:52:46 +08:00
const doc = new Y.Doc() // Initialize Y.Doc for shared editing
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Collaboration.configure({
2024-03-09 21:52:46 +08:00
document: doc // Configure Y.Doc for collaboration
})
],
content: `
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. Thats it. Its probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`,
})
return (
<EditorContent editor={editor} />
)
}
```
Your editor is now prepared for collaborative editing!
2024-03-09 21:52:46 +08:00
### Connecting to the Collaboration Server
2024-03-09 21:52:46 +08:00
For collaborative functionality, install the `@hocuspocus/provider` package:
```bash
npm install @hocuspocus/provider
```
Next, configure the Hocuspocus provider in your index.jsx file with your server details:
- **name**: Serves as the document identifier for synchronization.
2024-03-09 21:52:46 +08:00
- **appID**: Found in your [Cloud account](https://cloud.tiptap.dev/apps) after you started your app. For on-premises setups replace `appID` with `baseUrl`.
- **token**: Use the JWT from your [Cloud interface](https://cloud.tiptap.dev/apps/settings) for testing, but generate your own JWT for production.
Incorporate the following code to complete the setup:
```typescript
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'
// Importing the provider and useEffect
import {useEffect} from 'react'
import { TiptapCollabProvider } from '@hocuspocus/provider'
export default () => {
const doc = new Y.Doc()
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Collaboration.configure({
document: doc,
}),
],
content: `
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. Thats it. Its probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`,
})
// Connect to your Collaboration server
useEffect(() => {
const provider = new TiptapCollabProvider({
2024-03-09 21:52:46 +08:00
name: "document.name", // Unique document identifier for syncing. This is your document name.
appId: '7j9y6m10', // Your Cloud Dashboard AppID or `baseURL` for on-premises
token: 'notoken', // Your JWT token
document: doc,
})
})
return (
<EditorContent editor={editor} />
)
}
```
2024-03-09 21:52:46 +08:00
After following these steps, you should be able to open two different browsers and connect to the same document simultaneously through separate WebSocket connections.
2024-03-09 21:52:46 +08:00
For a clear test of the collaboration features, using two different browsers is recommended to guarantee unique websocket connections.
2024-03-09 21:52:46 +08:00
### Initializing Content Properly
Upon implementing collaboration in your Tiptap Editor, you might notice that the initial content is repeatedly added each time the editor loads. To prevent this, use the `.setContent()` method to set the initial content only once.
```typescript
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 '@hocuspocus/provider'
export default () => {
const doc = new Y.Doc()
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Collaboration.configure({
document: doc
})
],
// Remove the automatic content addition on editor initialization.
})
useEffect(() => {
const provider = new TiptapCollabProvider({
2024-03-09 21:52:46 +08:00
name: "document.name", // Unique document identifier for syncing. This is your document name.
appId: '7j9y6m10', // Your Cloud Dashboard AppID or `baseURL` for on-premises
token: 'notoken', // Your JWT token
document: doc,
// The onSynced callback ensures initial content is set only once using editor.setContent(), preventing repetitive content loading on editor syncs.
onSynced() {
if( !doc.getMap('config').get('initialContentLoaded') && editor ){
doc.getMap('config').set('initialContentLoaded', true);
editor.commands.setContent(`
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. Thats it. Its probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`)
}
}
})
})
return (
<EditorContent editor={editor} />
)
}
```
2024-03-09 21:52:46 +08:00
This ensures the initial content is set only once. To test with new initial content, create a new document by changing the `name` parameter (e.g., from `document.name` to `document.name2`).
## Disabling Default Undo/Redo
If you're integrating collaboration into an editor **other than the one provided in this demo**, you may need to disable the default history function of the Tiptap StarterKit. This is necessary to avoid conflicts with the collaborative history management.
```typescript
const editor = useEditor({
extensions: [
StarterKit.configure({
history: false, // Disables default history to use Collaboration's history management
}),
```
Following this guide will set up a basic, yet functional collaborative Tiptap Editor, synchronized through either the Collaboration Cloud or an on-premises backend.