Tracked changes

Create tracked text edits, inspect revisions by story, accept or reject changes, and handle unsupported review markup.

Set Document.changeTrackingMode to create tracked text suggestions through standard editing methods. Read existing revisions through RevisionCollection. See the limits on tracking modes and revision types in this guide.

Create a runtime with Runtime and setup. Use context and document proxies inside runtime.run().

Create a tracked replacement

Configure a nonempty author when creating the runtime. For browser tracked writes, install the Pro review module on an editable editor. Then enable TrackMineOnly and use an ordinary range edit:

await runtime.run(async (context) => {
  const matches = context.document.body.search('within 7 days', {
    matchCase: true,
  });
  matches.load('items');
  await context.sync();
  if (matches.items.length !== 1) throw new Error('Choose one deadline');
  context.document.changeTrackingMode = 'TrackMineOnly';
  matches.items[0]!.insertText('within 30 days', 'Replace');
  await context.sync();
});

Use insertText(text, 'Before' | 'After') for insertion suggestions. Use range.delete() or range.clear() for deletion suggestions. Inserted ranges require sync before dependent use. Mode assignments and edits commit together; a failed batch preserves the previous mode and document.

ChangeTrackingMode valueRuntime behavior
OffInitial mode; ordinary permanent edits
TrackMineOnlyText tracking for this runtime with an explicit author; browser writes require the Pro review module
TrackAllFails with NotSupported

The runtime's tracking setting does not change the browser editor UI mode. Read document.changeTrackingMode only after loading it. The mode persists across runs on that runtime. It does not change peers' tracking settings or save a document-wide tracking policy. Set Off explicitly only when your application intends permanent edits.

Stay within the tracked text domain

Tracked text edits support one paragraph, including table-cell text. The runtime rejects targets that touch pending revisions. A pending row insertion or deletion blocks tracked text edits throughout that row, including nested tables. While tracking changes, the runtime rejects formatting, lists, tables, pictures, breaks, control changes, and other structural edits. Comments and supported revision decisions remain available.

Never turn tracking off automatically to make an unsupported operation succeed. Report the limit or ask your application to choose a separately authorized permanent edit. For a multi-stage review, each successful sync becomes a separately committed suggestion. A later refusal does not roll back earlier suggestions.

Choose the revision text view

The runtime option revisionTextView affects ordinary text loads and search. allMarkup is the default. original retains pending deletions and hides pending insertions. This is a DocxEditor host option, not a Word document-model property. It does not accept or reject revisions.

Use plain text and explicit revision information when preparing a model prompt. Do not pass live proxies into a model or job queue. See Runtime and setup.

Inspect revisions by story

Document.revisions addresses the main story. Body.revisions addresses that body's story, including a header, footer, or note. It never merges all stories into one collection.

Load collection membership, then load author, date, and type:

const pending = await runtime.run(async (context) => {
  const revisions = context.document.revisions;
  revisions.load('items');
  await context.sync();
  for (const revision of revisions.items) {
    revision.load(['author', 'date', 'type']);
  }
  await context.sync();
  return revisions.items.map((revision) => ({
    author: revision.author,
    date: revision.date?.toISOString() ?? null,
    type: revision.type,
  }));
});

Revision.date is Date | null; narrow missing or invalid dates before using date methods. Revision.type uses the exported RevisionType vocabulary. Revision.range returns a range for the addressed revision. Resolve the range before reading or selecting its content. RevisionCollection exposes items, acceptAll(), and rejectAll(); it has no first-item accessor.

Accept or reject changes

Revision.accept() and Revision.reject() decide one supported revision. Use RevisionCollection.acceptAll() or rejectAll() to process all revisions in a story. A browser decision requires the review module and editable document, and joins the Undo history. A collection decision is one browser Undo unit.

For example, accept all resolvable revisions in the main story:

await runtime.run(async (context) => {
  context.document.revisions.acceptAll();
  await context.sync();
});

items contains only revisions that the API can represent as typed objects. Some structural records remain preserved but do not appear in items. acceptAll() and rejectAll() process every revision the store can resolve in that story, including complete tracked rows omitted from items.

If unsupported or read-only markup remains, the entire decision fails with an error such as NotImplemented. Preserve the document and let a reviewer resolve the remaining markup in Word when needed. On StaleDocument, start a fresh run, read again, and reconsider the decision. Recheck the target before retrying.

Next steps

See the server agent guide, Collaboration, and Batching, loading, and errors.

On this page