Manage threads in your editor
Use this guide to integrate comments directly into your editor. For a complete list of all Comments editor commands, see the Editor Commands page.
You can also interact with comments from outside your editor via our Comments REST API.
Learn about threads
Tiptap's Comments feature organizes discussions into threads, enabling clear and context-relevant collaboration by distinguishing between threads and individual comments.
Threads serve as containers for discussions related to specific document sections, while comments represent individual contributions within those threads.
Create a new thread
Let's assume you have a button to create a new thread. You can use the setThread
command to create a new thread at the current selection.
const createThread = () => {
editor
.chain()
.setThread({
content: 'This is a new thread', // the content of the threads first inital comment
})
.run()
}
This will create a new thread at the current selection and add a comment with the given content. By default comments and threads don't have a user or any other metadata assigned. Let's say you want to add the author to the thread and the comment. You can do this by passing through the data
and commentData
property to the setThread
command.
const createThread = () => {
const user = {
id: '123', // the user id of the author
name: 'John Doe', // the name of the author
avatarUrl: 'https://example.com/avatar.jpg', // the avatar of the author
}
editor
.chain()
.setThread({
content: 'This is a new thread', // the content of the threads first inital comment
data: {
user,
},
commentData: {
user,
},
})
.run()
}
Now the thread and comment will have a user assigned to it.
Receive and watch threads and comments
Receiving and watching the threads on your current document can easily be done by using the subscribeToThreads
function. This function will register a watcher, fetch the first initial list of threads and keep the list up to date.
To unsubscribe from the threads, you can call the callback function returned by the subscribeToThreads
function.
// Subscribe to threads
const unsubscribe = subscribeToThreads({
provider: yourTiptapCollabProvider,
callback: (threads) => {
// do something with threads, store in a state or variable from here
},
// optional options
getThreadsOptions: {
// only threads with the specific type will be fetched/watched, possible values are 'archived' and 'unarchived',
// if not set, only unarchived threads will be handled
// archived and unarchived threads represent soft-deleted threads
types: ['archived', 'unarchived'],
},
})
Receive and render threads manually
To receive the list of threads on your current document manually, you can simply call provider.getThreads()
. This will return an array of threads on the document connected to your provider.
This is a static array which won't update on its own. If you want to keep the list of threads up to date, you can listen to changes via the provider.watchThreads
and provider.unwatchThreads
functions.
// let's save threads in a variable
let threads = []
// this function is called whenever the threads change
const getThreads = () => {
threads = provider.getThreads()
}
// initial call to get the threads
getThreads()
// watch for changes
provider.watchThreads(getThreads)
To unwatch the threads you can call provider.unwatchThreads(getThreads)
.
provider.unwatchThreads(getThreads)
Let's say you want to write a react hook to get the threads and keep them up to date, you could write a hook like this.
const useThreads = (provider) => {
const [threads, setThreads] = useState([])
useEffect(() => {
if (!provider) {
return () => null
}
const getThreads = () => {
setThreads(provider.getThreads())
}
getThreads()
provider.watchThreads(getThreads)
return () => {
provider.unwatchThreads(getThreads)
}
}, [provider])
return threads
}
Now those threads will be reactive and can be used to render the threads in your UI.
Update a thread
To update a thread you can use the updateThread
command. This command will update the thread with the given id and update the content of the thread.
editor.commands.updateThread({
id: '123',
{
data: {
seen: true,
}
}
})
This will update the thread with the ID 123
and set the seen
property to true
.
Delete a thread
To delete a thread you can use the removeThread
command. This command will delete the thread with the given ID.
How to delete threads
By default, threads removed won't be deleted from the yjs document. To do this, you can pass
through the deleteThread
option to the removeThread
command.
editor.commands.removeThread({
id: '123',
deleteThread: true,
})
Create, update and delete comments
Comments can be added, edited, and removed within threads but cannot be marked as resolved, as they are considered parts of the thread discussions.
To create a comment on a thread you can use the createComment
command. This command will create a new comment on the thread with the given ID.
editor.commands.createComment({
threadId: '123',
content: 'This is a new comment', // this could also be tiptap JSON or any other type of content
data: {
user, // pass through any meta data you want - in this case the user
},
})
This will create a new comment on the thread with the ID 123
and set the content to This is a new comment
. You can also pass through any metadata you want to the comment.
To update a comment you can use the updateComment
command. This command will update the comment with the given ID and update the content of the comment.
editor.commands.updateComment({
threadId: '123', // the thread ID
id: '456', // the comment ID
content: 'Now this is the new content', // the new content of the comment
data: {
edited: true, // set the edited property to true
},
})
This will update the comment with the ID 456
on the thread with the ID 123
and set the content to Now this is the new content
. You can also pass through any metadata you want to the comment.
Finally you can delete a comment by using the deleteComment
command. This command will delete the comment with the given ID.
editor.commands.deleteComment({
threadId: '123',
id: '456',
})
Resolve and unresolve threads
To resolve a thread you can use the resolveThread
command. This command will resolve the thread with the given ID.
editor.commands.resolveThread({
id: '123',
})
This will resolve the thread with the ID 123
. To unresolve a thread you can use the unresolveThread
command. This command will unresolve the thread with the given ID.
If you want to resolve a thread and add information on which user resolved the thread, you can set the threads data to include the user who resolved the thread. Be sure to clear the data when unresolving the thread.
editor.commands.unresolveThread({
id: '123',
})
Select a thread
To select a thread you can use the selectThread
command. This command selects the thread with the specified ID.
editor.commands.selectThread({
id: '123',
})
This will move the cursor to the thread with the ID 123
.
To deselect a thread you can use the unselectThread
command. This command deselects the thread with the specified ID.
editor.commands.unselectThread({
id: '123',
})
You can also select or unselect threads without ID. In that case, the editor will select or unselect the thread at the current selection.