LoopIndex
Back to Blog

Developer Documentation Guide 2026: Track Changes, Comments

This Developer Documentation Guide shows how to implement track changes and inline comments in TinyMCE, CKEditor 4, and Froala. Get code.

Developer Documentation Guide 2026: Track Changes, Comments

developer documentation guide

TL;DR

This developer documentation guide covers everything you need to implement collaboration features (track changes and inline comments) in web-based rich text editors like TinyMCE, CKEditor 4, and Froala. It walks through integration patterns, API configuration, editor-specific setup, review workflow architecture, and common pitfalls. If you’re building a documentation platform, CMS, or any web app where multiple users need to collaboratively edit and review content, this is your technical reference.


Half of all developers lose 10 or more hours every week to non-coding tasks, according to Atlassian’s 2025 Developer Experience Report. A huge portion of that time goes to documentation workflows: writing, reviewing, and finalizing technical content. When those workflows live inside a web application, the rich text editor becomes the chokepoint. If it doesn’t support track changes or inline comments natively, review cycles spill out into email threads, Slack messages, and separate Google Docs, fragmenting the process.

The problem is that the three most widely used browser-based editors (TinyMCE, CKEditor 4, and Froala) don’t ship with full-featured collaboration tools out of the box. You either build them from scratch, which is months of engineering work, or integrate plugins purpose-built for the job.

This developer documentation guide is written for the developers and engineering managers making that decision. It covers the technical architecture of track changes and inline comments in web editors, provides integration code for each major platform, compares approaches, and documents the APIs you’ll work with. Whether you’re building an internal documentation tool, a SaaS content platform, or a legal review system, the patterns here apply.

For a quick look at what plugin-based collaboration looks like in practice, see the track changes plugin overview and inline comments plugin overview.


Why Rich Text Editors Need Collaboration Features

Web-based documentation platforms have replaced desktop word processors in most enterprise workflows. But the editors embedded in those platforms were originally designed for single-author content creation, not multi-user review cycles. This creates a gap.

The Review Workflow Problem

A typical documentation review involves at least three roles: the author (usually a developer), an editor or technical writer who refines language and structure, and a subject matter expert who verifies accuracy. Without track changes and inline comments built into the editor itself, teams resort to workarounds:

  • Copying content into Google Docs for review, then pasting it back
  • Using screenshots and annotations in project management tools
  • Leaving feedback in comment threads detached from the content

Each workaround breaks context. The reviewer can’t see the content in its final rendering environment. The author has to manually reconcile feedback from multiple sources. Version conflicts multiply.

What “Good Enough” Looks Like

A properly integrated review workflow keeps everything inside the editor. Reviewers highlight text and leave inline comments. Authors make edits that appear as tracked insertions and deletions. A reviewer can accept or reject each change individually. The full revision history is preserved and queryable. This is the standard that Google Docs and Microsoft Word set years ago, and it’s what users expect when they encounter any editing interface.

The question for developers isn’t whether to support these features. It’s how to implement them without rebuilding the editor from the ground up.


Editor Platform Comparison: TinyMCE vs. CKEditor 4 vs. Froala

Before diving into implementation, it’s worth understanding what each editor provides natively and where plugins fill the gaps.

TinyMCE

TinyMCE is the most widely deployed rich text editor on the web, used in WordPress, Jira, and thousands of custom applications. Its plugin architecture is mature and well-documented. TinyMCE’s premium plans include some collaboration features, but many teams find them either insufficient or too expensive at scale.

Third-party TinyMCE track changes plugins offer an alternative that integrates directly into TinyMCE’s plugin system without requiring a premium license for the base editor. This is particularly relevant for teams already running TinyMCE’s open-source or community edition.

CKEditor 4

CKEditor 4 remains heavily used in enterprise applications, government systems, and legacy platforms. While CKEditor 5 introduced real-time collaboration as a premium feature, CKEditor 4’s plugin ecosystem is where most existing integrations live. Adding track changes to CKEditor 4 requires a plugin approach since the editor itself doesn’t include this functionality.

Practitioners on Reddit report that migrating from CKEditor 4 to CKEditor 5 solely for collaboration features often isn’t practical due to breaking changes in the data model and plugin API. For teams staying on CKEditor 4, plugin-based track changes and inline comments are the primary path forward.

Froala

Froala is a lightweight, commercially licensed editor popular in SaaS applications where bundle size and initialization speed matter. Its plugin system is simpler than TinyMCE’s, which makes integration straightforward but also means fewer built-in options for collaboration.

Froala track changes plugins extend the editor without adding significant overhead. For implementation specifics, this guide walks through implementing track changes features in web editors with Froala-specific examples.

Feature Matrix

Feature TinyMCE (Core) CKEditor 4 (Core) Froala (Core) With Plugin
Bold/Italic/Lists N/A
Track Insertions
Track Deletions
Track Format Changes
Inline Comments
Accept/Reject Changes
Revision History Partial Partial
Author Attribution

The takeaway: none of the major editors include production-grade track changes or inline comments in their base distribution. This is a plugin problem.


Track Changes: Technical Integration

Track changes is the foundation of any documentation review workflow. It records insertions, deletions, and formatting modifications as discrete, reviewable units, each attributed to a specific author with a timestamp.

How Track Changes Works Under the Hood

At the DOM level, a track changes plugin wraps modified content in semantic markup. Inserted text gets wrapped in <ins> tags (or custom elements with data attributes). Deleted text is wrapped in <del> tags and rendered with strikethrough styling but not removed from the DOM until the change is accepted. Each wrapper carries metadata: author ID, timestamp, and a change identifier.

<!-- Example: tracked insertion -->
<p>The API requires <ins data-author="jane" data-time="2025-01-15T10:30:00Z" data-changeid="c42">OAuth 2.0</ins> authentication.</p>

<!-- Example: tracked deletion -->
<p>The API requires <del data-author="jane" data-time="2025-01-15T10:30:00Z" data-changeid="c43">basic auth</del> authentication.</p>

This approach keeps the change data inline with the content, which means the editor’s undo/redo stack, serialization, and storage all work without separate tracking infrastructure.

Initializing Track Changes in TinyMCE

After installing the track changes plugin, initialization follows TinyMCE’s standard plugin registration pattern:

tinymce.init({
  selector: '#editor',
  plugins: 'track-changes',
  toolbar: 'track-changes-toggle accept-change reject-change',
  track_changes_author: {
    id: 'user-123',
    name: 'Jane Developer'
  },
  track_changes_enabled: true,
  // Callback when changes are accepted or rejected
  track_changes_onaction: function(action, changeData) {
    console.log(action, changeData);
    // Persist to your backend
  }
});

The track_changes_author object ties each edit to a user in your system. In a multi-user application, you’d populate this from your authentication layer. For a complete walkthrough of editor-specific setup, the TinyMCE document review workflow guide covers configuration, toolbar customization, and backend persistence.

Accept/Reject API

The plugin API exposes methods for programmatic change management, which is essential when building review UIs outside the editor toolbar:

// Get all pending changes
const changes = editor.plugins.trackChanges.getChanges();

// Accept a specific change
editor.plugins.trackChanges.acceptChange('c42');

// Reject a specific change
editor.plugins.trackChanges.rejectChange('c43');

// Accept all changes (e.g., when finalizing a document)
editor.plugins.trackChanges.acceptAll();

This API lets you build custom review panels, batch operations, and approval workflows that match your application’s UX patterns rather than being locked into the editor’s default toolbar.

Persisting Change Data

Track changes data needs to survive page reloads. There are two common persistence strategies:

Inline persistence: Store the editor’s HTML content (including <ins> and <del> tags with metadata) directly in your database. When the editor loads, it parses these tags and reconstructs the change state. This is simpler but means your stored content contains review markup.

Sidecar persistence: Store clean content separately from a change manifest (a JSON array of change objects with positions, authors, and timestamps). This keeps your content clean but requires reconciliation logic when loading.

Most teams start with inline persistence because it’s easier to implement and debug. The revision history vs. track changes guide covers the tradeoffs in detail.


Inline Comments: Technical Integration

Inline comments let reviewers attach feedback to specific text selections without modifying the document content. They’re the “margin notes” of web-based editing.

Architecture

An inline comment system has three components:

  1. Text anchoring: Mapping a comment to a specific text range in the editor’s DOM
  2. Comment storage: Persisting comments with their anchor positions, author data, and thread state (open, resolved, deleted)
  3. Comment UI: Rendering a sidebar or popover that displays comments aligned with their anchored text

Text anchoring is the hardest part. Unlike a static document, a rich text editor’s DOM changes constantly as users type. A comment anchored to characters 45-60 in a paragraph will drift if someone inserts text before position 45. Good inline comment plugins handle this by anchoring to DOM nodes and offsets rather than character positions, and by updating anchors as the document changes.

Initializing Inline Comments

tinymce.init({
  selector: '#editor',
  plugins: 'inline-comments',
  toolbar: 'add-comment',
  inline_comments_author: {
    id: 'user-123',
    name: 'Jane Developer',
    avatar: '/avatars/jane.png'
  },
  inline_comments_onAdd: function(comment) {
    // POST to your backend
    return fetch('/api/comments', {
      method: 'POST',
      body: JSON.stringify(comment)
    });
  },
  inline_comments_onResolve: function(commentId) {
    return fetch(`/api/comments/${commentId}/resolve`, {
      method: 'PATCH'
    });
  }
});

The callback pattern means your application controls where comments are stored and how they’re managed. The plugin handles the UI and anchoring; your backend handles persistence and access control.

Comment Threading

Production comment systems need threading: replies to an initial comment that form a conversation. The data model looks like this:

{
  "commentId": "cmt-001",
  "anchor": {
    "paragraphId": "p-7",
    "startOffset": 12,
    "endOffset": 34
  },
  "author": { "id": "user-123", "name": "Jane Developer" },
  "text": "This endpoint description doesn't match the current response schema.",
  "timestamp": "2025-01-15T10:45:00Z",
  "resolved": false,
  "replies": [
    {
      "replyId": "rpl-001",
      "author": { "id": "user-456", "name": "Tom Engineer" },
      "text": "Updated. Can you verify the new schema?",
      "timestamp": "2025-01-15T11:02:00Z"
    }
  ]
}

For complete implementation details including thread resolution and notification hooks, see the guide on inline comments in web editors.


Building a Complete Review Workflow

Track changes and inline comments are features. A review workflow is the process that ties them together. Here’s the architecture that works for most documentation teams.

Workflow States

A document in a review workflow typically moves through four states:

Draft → In Review → Approved → Published

Each transition triggers specific editor behaviors:

  • Draft: Track changes may be off. The author is writing freely.
  • In Review: Track changes is on. The author’s identity is locked to their user account. Inline comments are enabled. The document may be read-only for non-reviewers.
  • Approved: All tracked changes have been accepted or rejected. All comments are resolved. The document is “clean.”
  • Published: The content is pushed to the public-facing documentation site.

Implementing State Transitions

function setDocumentState(editor, state) {
  switch (state) {
    case 'draft':
      editor.plugins.trackChanges.disable();
      editor.plugins.inlineComments.disable();
      editor.setMode('design'); // editable
      break;

    case 'in_review':
      editor.plugins.trackChanges.enable();
      editor.plugins.inlineComments.enable();
      editor.setMode('design');
      break;

    case 'approved':
      editor.plugins.trackChanges.acceptAll();
      editor.plugins.inlineComments.resolveAll();
      editor.setMode('readonly');
      break;

    case 'published':
      const cleanHTML = editor.getContent();
      publishToDocsSite(cleanHTML);
      break;
  }
}

This pattern gives product managers and engineering leads a clear model they can map to their existing approval processes. For a production example of this workflow, see the TinyMCE document review workflow guide.

Permission Models

Not every user should be able to accept changes or resolve comments. A typical permission matrix:

Role Edit Content View Changes Accept/Reject Comment Resolve Comments
Author
Reviewer
Admin
Viewer

The plugin API lets you enforce these permissions by selectively enabling or disabling toolbar buttons and API methods based on the current user’s role.


Integration Patterns and Architecture

How you integrate collaboration plugins depends on your application architecture. Here are the three most common patterns.

Pattern 1: Monolithic Web App

The editor is embedded in a server-rendered page (Rails, Django, Laravel). Change data is submitted with the form as part of the HTML content. The backend stores it in a database column alongside the document.

Pros: Simple. No additional infrastructure.
Cons: Change metadata is mixed into the HTML content. Querying changes (e.g., “show me all pending changes by user X”) requires parsing HTML.

Pattern 2: SPA with REST API

The editor is a component in a React, Vue, or Angular application. Changes and comments are persisted through API calls. The editor content and collaboration data may be stored separately.

// React component example
function DocumentEditor({ documentId, currentUser }) {
  const editorRef = useRef(null);

  useEffect(() => {
    tinymce.init({
      selector: `#editor-${documentId}`,
      plugins: 'track-changes inline-comments',
      track_changes_author: currentUser,
      inline_comments_author: currentUser,
      setup: (editor) => {
        editorRef.current = editor;
      }
    });

    return () => tinymce.get(`editor-${documentId}`)?.destroy();
  }, [documentId]);

  const handleSave = async () => {
    const content = editorRef.current.getContent();
    const changes = editorRef.current.plugins.trackChanges.getChanges();
    
    await fetch(`/api/documents/${documentId}`, {
      method: 'PUT',
      body: JSON.stringify({ content, changes })
    });
  };

  return (
    <div>
      <textarea id={`editor-${documentId}`} />
      <button onClick={handleSave}>Save</button>
    </div>
  );
}

Pattern 3: Docs-as-Code Hybrid

Content is ultimately stored in a Git repository as Markdown, but the web editor serves as a front-end for non-technical contributors. Changes made in the editor are converted to Markdown and committed as a branch. Track changes map to a pull request diff. Inline comments map to PR review comments.

This pattern is more complex but aligns with the docs-as-code philosophy where documentation lives alongside code in version control. Practitioners on Reddit’s r/technicalwriting frequently note that this hybrid approach is the only way to get both developers and non-technical writers contributing to the same documentation set.

For a broader look at how plugins fit into different editor architectures, the rich text editor plugin guide covers compatibility and configuration across all three patterns.


Common Integration Pitfalls

Developers on forums and in GitHub issues repeatedly run into the same problems when adding collaboration features to rich text editors. Here are the ones worth knowing about upfront.

Content Sanitization Conflicts

Many web apps sanitize HTML before storage to prevent XSS attacks. Default sanitization rules often strip <ins>, <del>, and custom data-* attributes, silently destroying all tracked changes. You need to whitelist the markup your track changes plugin uses.

// Example: DOMPurify configuration that preserves track changes markup
const clean = DOMPurify.sanitize(dirtyHTML, {
  ADD_TAGS: ['ins', 'del'],
  ADD_ATTR: ['data-author', 'data-time', 'data-changeid', 'data-comment-id']
});

Copy-Paste Contamination

When users paste content from Word or Google Docs, the clipboard HTML often contains its own <ins> and <del> tags from that application’s track changes. Without filtering, these get interpreted as tracked changes in your editor. Good plugins handle this by stripping foreign change markup on paste, but verify that yours does.

Editor Initialization Order

Plugins that modify the editor’s content handling (which track changes plugins do) are sensitive to initialization order. If your application loads content asynchronously and sets it after the editor initializes, tracked changes may not render correctly. Always set content before enabling the track changes plugin, or use the plugin’s loadChanges() method after content is ready.

Performance with Large Documents

Track changes adds DOM nodes. A document with hundreds of tracked changes can slow down the editor noticeably because each change wrapper is a separate DOM element that the editor must manage. For documents with extensive change history, consider periodically “finalizing” accepted changes (removing their tracking markup) to keep the DOM clean.


Measuring Collaboration Workflow Effectiveness

Once your review workflow is running, you need to know whether it’s actually working. These metrics tell you.

Review Cycle Time

The elapsed time from when a document enters “In Review” to when all changes are accepted and comments resolved. If this number is growing, your review process has a bottleneck, usually either too few reviewers or unclear ownership.

Change Acceptance Rate

The percentage of tracked changes that are accepted vs. rejected. A very high rejection rate might indicate that authors need better guidelines. A 100% acceptance rate might mean reviewers aren’t actually reviewing.

Comment Resolution Time

How long inline comments stay open before being resolved. Long-lived comments often indicate disagreements that should be resolved in a meeting rather than a comment thread.

Documentation Drift

The gap between what your documentation says and what your software actually does. Documentation drift happens when code changes ship without corresponding doc updates. Integrating your documentation workflow into your CI/CD pipeline, requiring doc updates in the same PR as code changes, is the most effective prevention. Google’s internal documentation guidelines warn that stale docs “misinform, slow down, and incite despair in engineers.”

Time to First Hello World (TTFHW)

For teams building developer-facing documentation, TTFHW measures how long it takes a new developer to go from discovering your product to making their first successful API call. Practitioners on developer forums report that anything over 15 minutes risks losing the developer entirely. Your review workflow should prioritize getting started guides through review quickly, because that’s the page where most developers decide whether to continue with a tool or abandon it.


Build vs. Plugin: Making the Decision

Engineering teams always face the build-or-buy question. For track changes and inline comments in rich text editors, the calculus is straightforward.

Building From Scratch

Building production-quality track changes requires:

  • Intercepting every content mutation in the editor (typing, pasting, formatting, deleting)
  • Wrapping mutations in semantic markup without breaking the editor’s internal data model
  • Building accept/reject logic that cleanly removes tracking markup
  • Handling edge cases (nested changes, overlapping selections, table operations, list manipulation)
  • Building a comment anchoring system that survives document edits
  • Testing across browsers and editor versions

Teams that have attempted this report 3 to 6 months of dedicated engineering time for a minimum viable implementation, with ongoing maintenance as the editor releases updates that change internal APIs.

Using Purpose-Built Plugins

Plugins from companies like Loop Index handle the editor-specific complexity and expose clean APIs for integration. The tradeoffs:

Plugin advantages: Immediate functionality, tested across editor versions, maintained by specialists, documented APIs for customization.

Plugin considerations: Dependency on a third party, licensing costs (starting at $333/year for inline comments or $500/year for track changes for up to 100 monthly active users), potential limitations in deeply custom scenarios.

For most teams, the math favors plugins. The engineering cost of building from scratch far exceeds years of plugin licensing, and the maintenance burden alone justifies the dependency. For pricing details and tier options, see the collaboration plugin pricing page.


Putting It All Together

Implementing documentation collaboration in a web-based editor comes down to three decisions:

  1. Which editor: TinyMCE, CKEditor 4, or Froala, each with different plugin architectures and tradeoffs
  2. Which features: Track changes, inline comments, or both, depending on your review workflow requirements
  3. Which integration pattern: Monolithic, SPA, or docs-as-code hybrid, driven by your existing application architecture

The technical integration is the easy part. The harder work is defining the review workflow that surrounds it: who can edit, who can review, what constitutes approval, and how changes flow from draft to published. Get the workflow right, and the plugin configuration follows naturally.

For teams ready to start integrating, the editor-specific guides provide step-by-step setup instructions: TinyMCE track changes, Froala track changes, and the general implementation guide for track changes in web editors.

If you have questions about compatibility with your specific editor version or integration architecture, reach out directly.


Frequently Asked Questions

What is this developer documentation guide about?

This guide covers how to integrate collaboration features (track changes and inline comments) into web-based rich text editors like TinyMCE, CKEditor 4, and Froala. It’s written for developers and engineering managers building documentation platforms, content management systems, or any web application where multiple users need to review and edit content collaboratively.

Do TinyMCE, CKEditor 4, and Froala support track changes natively?

No. None of these editors include production-grade track changes in their base distributions. CKEditor 5 offers collaboration as a premium feature, but CKEditor 4 does not. TinyMCE’s premium plans include limited collaboration tools. For most teams, especially those on open-source or standard editor licenses, track changes requires a plugin.

How do track changes plugins work in a rich text editor?

Track changes plugins intercept content mutations (insertions, deletions, formatting changes) and wrap them in semantic HTML tags like <ins> and <del> with metadata attributes for author, timestamp, and change ID. Reviewers can then accept or reject each change through toolbar buttons or API calls. Accepted changes are absorbed into the content; rejected changes are removed.

What is the difference between inline comments in code and inline comments in a review workflow?

Inline code comments are written directly in source files to explain implementation decisions. Inline comments in a review workflow are annotations attached to specific text selections in an editor, used by reviewers to provide feedback during the editing process. They exist in a separate layer from the content and can be resolved or deleted without affecting the document text.

How do I prevent content sanitization from stripping track changes markup?

Whitelist the HTML tags and attributes your track changes plugin uses in your sanitization library. For DOMPurify, add ins and del to the ADD_TAGS list and your plugin’s data attributes (like data-author, data-time, data-changeid) to the ADD_ATTR list. Test by making tracked changes, saving, reloading, and verifying the changes still render.

Should I build track changes from scratch or use a plugin?

For almost every team, plugins are the better choice. Building production-quality track changes from scratch requires 3 to 6 months of engineering time and ongoing maintenance. Plugin licensing for track changes starts at $500/year for up to 100 monthly active users, which is a fraction of the engineering cost. The primary reason to build from scratch is if you need behavior that no existing plugin can accommodate, which is rare.

How do I handle track changes in a docs-as-code workflow?

In a docs-as-code hybrid, the web editor serves as a front-end for non-technical contributors while content is ultimately stored as Markdown in Git. Track changes in the editor map conceptually to a pull request diff. One approach is to convert accepted editor changes to Markdown and commit them as a branch, using Git’s native diff and review tools for the final approval step.

What metrics should I track for documentation review workflows?

Focus on review cycle time (draft to published), change acceptance rate, comment resolution time, and documentation drift (the gap between what docs say and what the software does). These metrics tell you whether your review process is working or becoming a bottleneck.

Ready to add track changes to your editor?

FLITE and LANCE integrate in minutes with TinyMCE, Froala, and CKEditor 4.

Explore plugins →