Install the Tracked Changes extension
Install and configure the Tracked Changes extension by following this guide.
Install
First, contact our team to get access to the paid Tracked Changes add-on.
After gaining access, configure your package manager by following the private registry guide.
Then, install the package:
npm install @tiptap-pro/extension-tracked-changesBasic setup
import { Editor } from '@tiptap/core'
import { TrackedChanges } from '@tiptap-pro/extension-tracked-changes'
const editor = new Editor({
extensions: [
TrackedChanges.configure({
enabled: true,
userId: 'user-123',
userMetadata: { name: 'John Doe' },
}),
],
})Settings
enabled
Enable or disable track changes mode. When enabled, all edits become suggestions instead of direct changes.
Default: false
TrackedChanges.configure({
enabled: true,
})userId
The ID of the current user making suggestions. This should come from your authentication system.
Default: 'anonymous'
TrackedChanges.configure({
userId: 'user-123',
})userMetadata
Arbitrary metadata about the current user, stored as a JSON-serializable object on each suggestion. Useful for storing display names, avatars, or other custom data alongside the suggestion without requiring a separate user store.
Default: null
TrackedChanges.configure({
userId: 'user-123',
userMetadata: {
name: 'John Doe',
avatar: 'https://example.com/avatar.jpg',
role: 'editor',
},
})onSuggestionCreate
Callback fired when a new suggestion is created. Receives the suggestion object containing id, type, userId, createdAt, from, to, and text.
Default: undefined
TrackedChanges.configure({
onSuggestionCreate: (suggestion) => {
console.log('New suggestion created:', suggestion)
// Update your UI, notify other users, etc.
},
})onSuggestionAccept
Callback fired when a suggestion is accepted. Receives the suggestion ID.
Default: undefined
TrackedChanges.configure({
onSuggestionAccept: (id) => {
console.log('Suggestion accepted:', id)
},
})onSuggestionReject
Callback fired when a suggestion is rejected. Receives the suggestion ID.
Default: undefined
TrackedChanges.configure({
onSuggestionReject: (id) => {
console.log('Suggestion rejected:', id)
},
})blockSplitMarker
The marker shown where a block split was suggested. It is rendered at the end of the block before the split.
Default: '¶'
Pass a string to change the character:
TrackedChanges.configure({
blockSplitMarker: '↵',
})Pass an element, or a function returning an element, for full control over the markup:
TrackedChanges.configure({
// A function is called once per marker and must return a new element each time
blockSplitMarker: () => {
const marker = document.createElement('span')
marker.className = 'my-split-marker'
marker.textContent = '¶'
return marker
},
})Pass null to render no marker at all:
TrackedChanges.configure({
blockSplitMarker: null,
})A single HTMLElement also works and is cloned for each marker. Whatever you return, the extension sets data-tracked-change-split="true", contenteditable="false", and disables selection and pointer events on it, so the marker never becomes editable content. See styling for the default CSS.