Review tracked changes

Let people propose, inspect, accept, and reject changes in the Editor.

Tracked changes let a person propose an edit without immediately changing the accepted document. The Editor displays each proposal inline in the document and provides controls for accepting or rejecting it.

Use this page for the human review experience. Use Document API tracked changes when application code needs to create, list, inspect, or decide changes programmatically.

Open the Editor for review

Start in suggesting mode when a reviewer should create new tracked changes while inspecting existing ones. Provide the current user so exported changes retain their author.

Use the same toolbar and Editor containers from Configure the built-in toolbar, then initialize SuperDoc:

import { SuperDoc } from 'superdoc';
import 'superdoc/style.css';

const superdoc = new SuperDoc({
  selector: '#editor',
  document: '/contract.docx',
  documentMode: 'suggesting',
  toolbar: '#toolbar',
  user: {
    name: 'Jordan Lee',
    email: '[email protected]',
  },
});

window.addEventListener('beforeunload', () => superdoc.destroy());

Copy the tracked-changes fixture to your app's public directory as contract.docx, or update the document URL.

The built-in toolbar reads the active selection and exposes accept or reject actions when a tracked change can be decided. Anything you type in suggesting mode becomes a new proposal rather than a direct edit.

Try the review flow

The sample opens automatically with one tracked change. Select the change, then accept or reject it.

Review a tracked changeLoads the sample DOCX in suggesting mode.
Loading…

The sample editor loads as this demo enters view. The rest of the article stays lightweight.

Accepting a change keeps the proposed result and removes the review mark. Rejecting it restores the prior content and removes the review mark. Both decisions change the open document and must be followed by your normal save or export flow.

Choose the right mode

Reviewer taskModeTracked-change visibility
Propose edits and decide existing changessuggestingReview marks are shown
Edit directly while deciding existing changeseditingReview marks are shown
Inspect proposals without changing the documentviewingSet modules.trackChanges.visible to true
Read the document as if no proposals had been madeviewingLeave tracked-change visibility at its default

Viewing mode is read-only. Showing tracked changes in that mode does not grant permission to accept, reject, or create them.

Control review decisions

Turn off accept and reject when someone may inspect or discuss proposals but should not decide them:

const config = {
  interaction: {
    trackedChanges: {
      allowDecisions: false,
    },
  },
};

This does not stop someone from proposing changes. Use documentMode: 'suggesting' to record their edits as proposals, or documentMode: 'viewing' to prevent document edits entirely.

Keep review decisions explicit

The built-in controls and superdoc/ui use the same tracked-change state. A control can be disabled because there is no active change, the document is read-only, or the current client interaction policy does not allow the decision.

Do not infer the active change from document DOM attributes. Use the built-in controls or the public custom UI controller. Use the Document API when a service or application workflow decides a known change by ID.

Editor modes and client-side review controls are not an authorization boundary. Your application still owns access to the DOCX, trusted user identity, persistence, and collaboration authorization.

Verify the completed workflow by exporting the DOCX and reopening it. Accepted text should remain without a pending review mark. Rejected text should be restored. Unresolved changes should remain available for another reviewer.

Report permission-filtered bulk decisions

Accept All and Reject All can leave some changes open when the permission resolver allows the decision for only part of the document. SuperDoc does not choose how to present that outcome. Subscribe to onTrackedChangesBulkDecision and render a toast, banner, activity entry, or other application-owned UI.

const status = document.querySelector<HTMLOutputElement>('#review-status');

const superdoc = new SuperDoc({
  selector: '#editor',
  document: '/contract.docx',
  onTrackedChangesBulkDecision: (result) => {
    if (!status || result.permissionDeniedCount === 0) return;

    const action = result.decision === 'accept' ? 'Accepted' : 'Rejected';
    status.value = `${action} ${result.successfulCount} changes. ${result.permissionDeniedCount} changes were left because you do not have permission.`;
  },
});

The same payload is available through superdoc.on('tracked-changes:bulk-decision', listener) when the listener belongs to a later application lifecycle.

FieldMeaning
documentIdDocument that received the bulk decision
decisionRequested operation: accept or reject
requestedCountUnique tracked changes considered
successfulCountChanges successfully decided
permissionDeniedCountChanges left open because the permission resolver denied the decision

requestedCount equals successfulCount + permissionDeniedCount. A zero permissionDeniedCount means the permission resolver allowed every considered change; applications can ignore that outcome when they only need to report leftover changes.

Continue with Load and save documents, or build application-owned controls with the Custom UI overview.

On this page