Comments
Read comment threads, create anchored comments, add replies, resolve threads, and delete review data.
Use comments for discussion anchored to document content. Use Tracked changes to propose text edits for review. Comments and replies are separate proxies with shared author, date, ID, and text properties.
Create a runtime with Runtime and setup.
Use context and document proxies inside runtime.run().
Configure review writes
Supply a nonempty author when creating the runtime for comment creation and replies.
The API does not obtain an identity from a signed-in Office account.
Browser review writes also require the Pro review module, an editable mode, and an attached writable document.
The server runtime supplies its own Pro-licensed review implementation.
These conditions are dynamic; there is no static comment-write capability flag.
Handle NotSupported, NotImplemented, and other typed errors from the call or sync().
Do not assume that a successful read permits a write.
Read threads and replies
Document.comments returns comments anchored in the main body story.
Body.getComments() addresses comments in that body story.
CommentCollection and CommentReplyCollection expose items and getFirst().
A first-item lookup fails with ItemNotFound on an empty collection.
Load thread properties after loading membership:
const threads = await runtime.run(async (context) => {
const comments = context.document.comments;
comments.load('items');
await context.sync();
for (const comment of comments.items) {
comment.load(['id', 'authorName', 'creationDate', 'text', 'resolved']);
}
await context.sync();
return comments.items.map((comment) => ({
id: comment.id,
author: comment.authorName,
date: comment.creationDate?.toISOString() ?? null,
text: comment.text,
resolved: comment.resolved,
}));
});Comment.replies returns a reply collection in document order.
Load its items, then load reply properties in another batch.
Both objects expose authorName, creationDate, id, and text.
creationDate is Date | null; missing or invalid DOCX dates return null.
text is a DocxEditor read extension, not an editable comment body.
Comment-body replacement is unavailable.
Create an anchored comment
Range.insertComment(commentText) returns a Comment over the exact range.
A collapsed range creates an insertion-point comment.
The runtime rejects empty comment text and ranges that cross table cells.
This example comments on a unique phrase, then adds a reply:
await runtime.run(async (context) => {
const matches = context.document.body.search('Payment is due');
matches.load('items');
await context.sync();
if (matches.items.length !== 1) throw new Error('Choose one payment clause');
const comment = matches.items[0]!.insertComment('Confirm the payment deadline.');
await context.sync();
const reply = comment.reply('Check the signed order form.');
await context.sync();
reply.load('text');
await context.sync();
console.log(reply.text);
});Comment.reply(replyText) returns the created CommentReply.
Sync after creation before using either returned object for dependent work.
Author names can repeat; the runtime preserves them as stored.
Navigate and resolve a thread
Comment.getRange() returns the content range for the comment.
Resolve that range before reading text or selecting it in a browser.
Comment.resolved = true resolves the whole thread.
Assign false to reopen it.
Load resolved before reading its state.
Resolving a thread does not delete its text or replies.
For example, resolve a comment already selected by your application:
comment.resolved = true;
await context.sync();Keep the selected comment inside its run, or explicitly track and adopt it. See Batching, loading, and errors.
Delete threads or replies
Comment.delete() removes the root comment, its replies, and its anchors.
CommentReply.delete() removes only that reply and preserves its parent and siblings.
Queue independent deletions together when they should form one atomic transaction:
await runtime.run(async (context) => {
const comments = context.document.comments;
comments.load('items');
await context.sync();
for (const comment of comments.items.slice(0, 2)) comment.delete();
await context.sync();
});You can undo a browser deletion batch in one step. Server writes use the same object-model methods without a browser module. Deleted targets become invalid, and stale reads require fresh selection and reconsideration.
Next steps
See Runtime and setup, Search and navigation, and API member directory.