Install the Tracked Changes extension
Install and configure the Tracked Changes extension by following this guide.
Install
Tracked Changes is a paid add-on that isn't included in any plan. Test it during your free trial or purchase it in your dashboard.
Then 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.