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.

You can also read a dedicated blog post that compares the track changes with revision history and points out similarities and differences between these two features.

# 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.

# Use as a standalone plugin

Track changes does not require real-time collaboration to work. If you prefer a more traditional approach with asynchronous 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.

You can read more about CKEditor 5’s collaboration features and their real life implementations in this dedicated blog post.

# 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”:

    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>.

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>

Adding bold:

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

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:...">
    <suggestion-td data-suggestion-end-after="deletion:..." data-suggestion-start-before="deletion:...">

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:

    <span class="ck-suggestion-marker ck-suggestion-marker-formatInline">

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
        } )

# 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.

# Track changes feature customization

The track changes feature is highly customizable. Please refer to the Annotation customization section and Track changes API overview to learn more.

# Enabling and disabling track changes by default

Enabling track changes by default is very easy and can be achieved with just one line of code, which executes the track changes Command:

editor.execute( 'trackChanges' );

This should be used when creating the editor instance:

    .create( document.querySelector( '#editor' ), {
    } )
    .then( editor => {
        // Execute track changes command here
        editor.execute( 'trackChanges' );
    } )
    .catch( error => console.error( error ) );

This way, every time you initialize and open the editor, track changes will be turned on and ready to use.

If, on the other hand, your use case is to disable track changes completely, you can achieve this by blocking proper commands with Command#forceDisabled():

editor.commands.get( 'trackChanges' ).value = false;
editor.commands.get( 'trackChanges' ).forceDisabled( 'customId' );
editor.commands.get( 'acceptSuggestion' ).forceDisabled( 'customId' );
editor.commands.get( 'acceptAllSuggestions' ).forceDisabled( 'customId' );
editor.commands.get( 'discardAllSuggestions' ).forceDisabled( 'customId' );
editor.commands.get( 'discardSuggestion' ).forceDisabled( 'customId' );

// NOTE: customId can be used later on to enable commands using clearForceDisabled method
// Different Id's can be used for different commands

The key here is to disable commands when track changes is off, which can be achieved either by not executing trackChanges command (the one from the previous example) or by setting its value to false.

# 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);

If you want to change the appearance of a single suggestion box (placed in the sidebar), refer to the annotations theme customization guide.