Report an issue

guideTrack changes overview

This feature enables the track changes mode (also known as the “suggestion mode”) in CKEditor 5. They allow to follow the history of changes, edits and corrections made by different editors and also allow to easily accept or decline the introduced changes.

Apart from reading this guide, we encourage you to read a dedicated blog post which compares the track changes with revision history and another blog post discussing CKEditor 5’s collaboration features and their real life implementations.

# Demo

You can test the track changes feature in the editor below. Use the toolbar dropdown Track changes to enable changes tracking and mass accept or decline suggestions. Use the side panel to work with individual changes.

In this mode, changes done by the users are marked in the content and shown as suggestions in the sidebar. Suggestions can be accepted or discarded by the users. The suggestion balloon is then closed and the change is no longer marked.

Suggestion annotations can be displayed in a sidebar or as inline balloons. Visit the display mode guide to learn how to configure the display mode. The mode specified for comments is also set for track changes.

This sample automatically switches between display modes according to the screen size. Resize the window and observe how the editor changes its appearance.

# Integration

# Use as a standalone plugin

Track changes does not require real-time collaboration to work. If you prefer a more traditional approach to document editing, track changes can be added to CKEditor 5 just like any other plugin.

To learn how to integrate track changes as a standalone plugin, please refer to the Integrating track changes with your application guide.

# Use with real-time collaboration

If you are using the real-time collaboration feature, refer to the Real-time collaboration features integration guide.

# Learn more

After you managed to run track changes feature in your editor, you might want to learn more about the feature. Find oud how it works, how it can be configured, customized, and extended, to fit your application the best way possible.

# Configuration

The configuration for the track changes feature can be found in the TrackChangesConfig API reference.

# Suggestions markup

Suggestions are always attached to some place in the document. To make sure that they will not be lost, the track changes plugin adds some special markup to the document:

  • <suggestion-start> and <suggestion-end> tags are added if the suggestion starts/ends in text,
  • otherwise, the following attributes are added on elements:
    • data-suggestion-start-before,
    • data-suggestion-end-after,
    • data-suggestion-start-after,
    • data-suggestion-end-before.

Also, <suggestion-td> tag is used for table cells pasting suggestions to separate old content (original) from the new content (pasted).

Read more about marker-to-data conversion to understand what data you may expect.

Examples of the possible mark-up:

Replacing word “chocolate” with word “ice-creams”:

<p>
    I like
    <suggestion-start name="insertion:e8ghd7:e390dk"></suggestion-start>chocolate<suggestion-end name="insertion:e8ghd7:e390dk"></suggestion-end>
    <suggestion-start name="deletion:ejd853:e390dk"></suggestion>ice-creams<suggestion-end name="deletion:ejd853:e390dk"></suggestion-end>.
</p>

Inserting image:

<figure class="image" data-suggestion-end-after="insertion:e1f0810:eohfu9" data-suggestion-start-before="insertion:e1f0810:eohfu9">
    <img src="foo.jpg">
    <figcaption>Image caption.</figcaption>
</figure>

Adding bold:

<p>
    This is
    <suggestion-start name="formatInline:fsao87:ekeij:e3404"></suggestion-start>
    important
    <suggestion-end name="formatInline:fsao87:ekeij:e3404"></suggestion-end>
    .
</p>

Pasting table cell with text “New” into a table cell with text “Old”:

<td ...>
    <suggestion-td data-suggestion-end-after="insertion:..." data-suggestion-start-before="insertion:...">
        <p>New</p>
    </suggestion-td>
    <suggestion-td data-suggestion-end-after="deletion:..." data-suggestion-start-before="deletion:...">
        <p>Old</p>
    </suggestion-td>
</td>

Note that if your application filters HTML content, for example to prevent XSS, make sure to leave the suggestion tags and attributes in place when saving the content in the database. The suggestion markup is necessary for further editing sessions.

# Saving the data without suggestions

If you need to get the editor data with all the existing suggestions accepted or discarded, please refer to the dedicated guide.

# Saving the data with suggestion highlights

By default, the data returned by editor.getData() contains the markup for the suggestions as described above. It does not provide the markup that visually shows the suggestion highlights in the data (similarly to how they are shown in the editor).

It is possible to change the editor output using the showSuggestionHighlights option passed in editor.getData(). When set, the editor output will return suggestions similarly to how they are present inside the editor:

editor.getData( { showSuggestionHighlights: true } );

Will return:

<p>
    <span class="ck-suggestion-marker ck-suggestion-marker-formatInline">
        Foo
    </span>
    bar
</p>

Note that the output data generated using the showSuggestionHighlights option cannot be used to load the editor data (it cannot be passed to editor.setData())!

This feature should be used for preview purposes and can be used, for example, together with the export to PDF feature.

The export to PDF feature can be integrated with the suggestion highlights as shown below:

{
    exportPdf: {
        // ...
        dataCallback: editor => editor.getData( {
            showSuggestionHighlights: true
        } )
    }
}

# Force track changes mode to be enabled

If you would like to have track changes enabled by default, execute the trackChanges command, which toggles the track changes mode. It should be done after the editor instance is initialized:

ClassicEditor
    .create( document.querySelector( '#editor' ), {
        // ...
    } )
    .then( editor => {
        editor.execute( 'trackChanges' );
    } )
    .catch( error => console.error( error ) );

You can disable the trackChanges command to prevent turning the track changes on or off. This can be useful for example when a particular user has permissions only to create suggestions in a given document. You can disable the command by calling Command#forceDisabled():

ClassicEditor
        .create( document.querySelector( '#editor' ), {
            // ...
        } )
        .then( editor => {
            editor.execute( 'trackChanges' );

            editor.commands.get( 'trackChanges' ).forceDisabled( 'suggestionsMode' );
        } )
        .catch( error => console.error( error ) );

To prevent a user from accepting or discarding suggestions, disable commands responsible for these actions:

ClassicEditor
        .create( document.querySelector( '#editor' ), {
          // ...
        } )
        .then( editor => {
          editor.execute( 'trackChanges' );

          editor.commands.get( 'trackChanges' ).forceDisabled( 'suggestionsMode' );
          editor.commands.get( 'acceptSuggestion' ).forceDisabled( 'suggestionsMode' );
          editor.commands.get( 'acceptAllSuggestions' ).forceDisabled( 'suggestionsMode' );
          editor.commands.get( 'discardAllSuggestions' ).forceDisabled( 'suggestionsMode' );
          editor.commands.get( 'discardSuggestion' ).forceDisabled( 'suggestionsMode' );
        } )
        .catch( error => console.error( error ) );

Keep in mind that the 'suggestionsMode' identifier can be later used to enable commands using Command#clearForceDisabled().

# Markers styling

Similarly to everywhere in the CKEditor 5 Ecosystem, we have used CSS Variables to let the developers easily customize the design of such UI elements as, for example, suggestion markers. You can easily override these properties with a .css file or place your customizations directly into the <head> section of your page, but in this case you will need to use a more specific CSS selector than :root (e.g. <body>).

Check out the color sheet for the full list of customizable colors. You can also browse other files with CSS Variables in CKEditor 5.

Here you can find the default CSS Variables used for the track changes feature:

:root {
    /* You can override the design of suggestion markers in the content. */

    /* Variables responsible for suggestions for text: */
    --ck-color-suggestion-marker-insertion-border: hsla(128, 71%, 40%, .35);
    --ck-color-suggestion-marker-insertion-border-active: hsla(128, 71%, 25%, .5);
    --ck-color-suggestion-marker-insertion-background: hsla(128, 71%, 65%, .35);
    --ck-color-suggestion-marker-insertion-background-active: hsla(128, 71%, 50%, .5);

    --ck-color-suggestion-marker-deletion-border: hsla(345, 71%, 40%, .35);
    --ck-color-suggestion-marker-deletion-border-active: hsla(345, 71%, 25%, .5);
    --ck-color-suggestion-marker-deletion-background: hsla(345, 71%, 65%, .35);
    --ck-color-suggestion-marker-deletion-background-active: hsla(345, 71%, 50%, .5);
    --ck-color-suggestion-marker-deletion-stroke: hsla(345, 71%, 20%, .5);

    --ck-color-suggestion-marker-format-border: hsla(191, 90%, 40%, .4);
    --ck-color-suggestion-marker-format-border-active: hsla(191, 90%, 40%, .65);

    /* Variables responsible for the left border of the suggestion boxes in the sidebar: */
    --ck-color-comment-box-border: hsl(55, 98%, 48%);
    --ck-color-suggestion-box-deletion-border: hsl(345, 62%, 60%);
    --ck-color-suggestion-box-insertion-border: hsl(128, 62%, 60%);
    --ck-color-suggestion-box-format-border: hsl(191, 62%, 60%);

    /* Variables responsible for the styling of suggestions for widgets: */
    --ck-color-suggestion-widget-insertion-background: hsla(128, 71%, 65%, .05);
    --ck-color-suggestion-widget-insertion-background-active: hsla(128, 71%, 50%, .07);
    --ck-color-suggestion-widget-deletion-background: hsla(345, 71%, 65%, .05);
    --ck-color-suggestion-widget-deletion-background-active: hsla(345, 71%, 45%, .07);
    --ck-color-suggestion-widget-format-background: hsla(191, 90%, 40%, .09);
    --ck-color-suggestion-widget-format-background-active: hsla(191, 90%, 40%, .16);

    --ck-color-suggestion-widget-th-insertion-background: hsla(128, 71%, 65%, .1);
    --ck-color-suggestion-widget-th-insertion-background-active: hsla(128, 71%, 50%, .12);
    --ck-color-suggestion-widget-th-deletion-background: hsla(345, 71%, 65%, .1);
    --ck-color-suggestion-widget-th-deletion-background-active: hsla(345, 71%, 45%, .12);
}

# API overview

Check the track changes API documentation for detailed information about the track changes API. Making yourself familiar with the API may help you understand the code snippets.

# Suggestions annotations customization

The suggestions annotations are highly customizable. Please refer to the Annotation customization guide to learn more.

# Integration with custom features

If you provide your own plugins, you may want to integrate these custom features with track changes mode.