const superdoc = new SuperDoc({ selector: '#editor', document: 'contract.docx', user: { name: 'John Smith', email: 'john@company.com' }, modules: { comments: { readOnly: false, allowResolve: true, element: '#comments' } }, onCommentsUpdate: ({ type, comment }) => { console.log('Comment event:', type); } });
modules: { comments: { element: '#comments-sidebar' } }
superdoc.on('ready', () => { const sidebar = document.querySelector('#comments-sidebar'); superdoc.addCommentsList(sidebar); });
onCommentsUpdate
Show Event types
pending
add
update
delete
resolved
selected
onCommentsUpdate: ({ type, comment, meta }) => { switch(type) { case 'pending': showCommentDialog(); break; case 'add': await saveComment(comment); break; case 'resolved': await markResolved(comment.id); break; } }
Hide Core properties
Show Author information
Show Position
Show State
Show Track changes
Show Import metadata
// Parent comment const parent = { commentId: 'parent-123', commentText: 'Should we change this?', parentCommentId: null }; // Reply const reply = { commentId: 'reply-456', commentText: 'Yes, let\'s update', parentCommentId: 'parent-123' }; // Nested reply const nested = { commentId: 'reply-789', commentText: 'Done', parentCommentId: 'reply-456' };
onCommentsUpdate: ({ type, comment }) => { if (type === 'resolved') { const resolution = { commentId: comment.commentId, resolvedTime: comment.resolvedTime, resolvedByName: comment.resolvedByName, resolvedByEmail: comment.resolvedByEmail }; await api.resolveComment(resolution); notifyParticipants(comment); } }
const canResolve = (comment, user, role) => { // Document owners can always resolve if (role === 'editor') return true; // Authors can resolve their own if (comment.creatorEmail === user.email) return true; return false; };
importedId
const importedComment = { commentId: 'uuid-generated', importedId: 'w15:123', // Original Word ID importedAuthor: { name: 'John Smith (imported)', email: 'john@company.com' }, parentCommentId: 'parent-uuid' // Relationships preserved };
Show Options
external
clean
// With comments const blob = await superdoc.export({ commentsType: 'external', isFinalDoc: false }); // Clean version const cleanBlob = await superdoc.export({ commentsType: 'clean', isFinalDoc: true });
Show properties
true
insertComment
superdoc.activeEditor.commands.insertComment({ commentText: 'Review this section', creatorName: 'John Smith', creatorEmail: 'john@company.com' });
removeComment
superdoc.activeEditor.commands.removeComment({ commentId: 'comment-123' });
setActiveComment
superdoc.activeEditor.commands.setActiveComment({ commentId: 'comment-123' });
resolveComment
superdoc.activeEditor.commands.resolveComment({ commentId: 'comment-123' });
modules: { comments: { allowResolve: false, // Only owner resolves element: '#legal-comments' } } onCommentsUpdate: ({ type, comment }) => { // Track progress if (type === 'add') stats.total++; if (type === 'resolved') stats.resolved++; // Auto-assign if (comment.commentText.match(/\bprice|cost\b/i)) { assignToFinanceTeam(comment); } }
modules: { comments: { useInternalExternalComments: true } } onCommentsUpdate: ({ comment }) => { if (comment.isInternal) { syncToInternalTeam(comment); } else { syncToAllUsers(comment); } }
import { debounce } from 'lodash'; const saveComment = debounce(async (comment) => { await api.updateComment(comment.commentId, comment); }, 1000); onCommentsUpdate: ({ type, comment }) => { if (type === 'update') { saveComment(comment); } }
const MAX_COMMENTS = 500; onCommentsUpdate: ({ type }) => { if (type === 'add' && commentCount >= MAX_COMMENTS) { showWarning('Maximum comments reached'); return false; } }
Was this page helpful?