Report an issue

guideComments overview

The Comments plugin makes it possible to add comments to any part of rich-text content in CKEditor 5, including text and block elements such as embedded media or images.

Commented content is marked as highlighted and a corresponding comment is displayed in the sidebar.

CKEditor 5 rich-text editor users collaborating on a document via comments.

Comments can be added, edited, deleted and replied to, allowing the users to collaborate on the same document directly in the rich-text editor.

The comments feature can be used together with real-time collaboration or as a standalone plugin where the comments are saved in your application using a custom integration.

A comments-only mode is available, too, if you want to limit the user permissions and only allow them to add comments to the document, but not edit it directly.

# Installation

The comments feature is not included in any official CKEditor 5 build, so you need to create a custom build to run it. You also need to set up the sidebar container next to your editor content where the comments should be rendered and, finally, define where the data should be stored. This guide will help you define all of these elements.

# HTML structure for the editor with the sidebar

The comments plugin requires a two-column layout to be prepared before the editor initialization:

  • The main column for the editor element.
  • The sidebar column as a container for the sidebar with comments.

The column order and size are not important here. The sidebar can be placed on the right or on the left side and any column size can be set in CSS.

What is important is that the editor and sidebar elements should be positioned elements (relative for their children) and should have the same top offset for their positioned children. When the editor top offset is not the same as the sidebar top offset, the comments and their corresponding markers will be misaligned.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>CKEditor 5 Collaboration with comments</title>
        <style type="text/css">
         #container {
             /* To create the column layout. */
             display: flex;

             /* To make the container relative to its children. */
             position: relative;
         }

         #container .ck.ck-editor {
             /* To stretch the editor to max 700px 
                (just to look nice for this example but it can be any size). */
             width: 100%;
             max-width: 700px;
         }

         #sidebar {
            /* Set some size for the sidebar (it can be any). */
            min-width: 300px;

            /* Add some distance. */
            padding: 0 10px;
         }
        </style>
    </head>
    <body>
        <div id="container">
            <div id="editor">
                <p>Let's edit this together!</p>
            </div>
            <div id="sidebar"></div>
        </div>
    </body>
    <script src="build/ckeditor.js"></script>
</html>

# Data adapter

The comments plugin needs an adapter to know where the data should be stored. There are two options available when it comes to the comments adapter:

  • You can use comments as a part of the real-time collaboration. In this scenario the comments will use CKEditor Cloud Services to store the data and this solution will work out of the box. Additionally, in such case you do not need to define the application key, however, you need to have your Cloud Services token.

  • You provide your own comments integration. This way you will be able to control where the data is stored. In such case you will need an application key to authenticate. If you do not have a key yet, please contact us.

# Prepare a custom build

The comments feature is not included in any official CKEditor 5 build. To enable it, you need to create a custom rich-text editor build that includes the collaboration feature. We recommend getting familiar with installing plugins as you will need to understand it in order to run the collaboration examples.

Depending on where you want to store the comments, check the Real-time collaborative comments or Integrating comments with your application guides to find information about how to assemble a custom build and to see examples of the sample JavaScript code.

When you are ready with your custom build, return to this guide to see additional information about comments.

# Saving comments

Comments are always attached to some place in the document. To make sure that they will not be lost, the comments plugin adds special markers to the document:

> editor.getData();
<- '<p>They are <comment id="b39dd790" type="start"></comment>awesome<comment id="b39dd790" type="end"></comment>.</p>'

The position of comments in the body is marked with custom <comment> tags. Separate elements for the beginning and the end of a comment are used to make cleanup simpler when you want to render the page using the content generated by the editor.

There is nothing to worry about this extra markup. However, if your application filters HTML content, for example to prevent XSS, make sure to leave <comment> tags in place, at least for the purpose of passing the content back to the editor for further editing. If <comment> tags are missing, the editor will not know about any comments added to the document.

So, with the example content above, to display the document on your website the <comment> tags may be removed:

<p>They are awesome.</p>

When launching the editor, though, make sure to include them in the HTML:

<div id="container">
    <div id="editor">
        <p>They are <comment id="b39dd790" type="start"></comment>awesome<comment id="b39dd790" type="end"></comment>.</p>
    </div>
    <div id="sidebar"></div>
</div>

# Why is there no comments data in content?

Note that markers only store comment thread IDs. Why do they not include any content? Why do you need to write an adapter?

The reason is security. If you stored the whole comment discussion in the markup, one could edit it, including comments written by other authors. It would be very hard to check which changes in the comments the user has done when saving data. You would need to deeply analyze the whole content of the document and compare it to the previous version. Considering that both content and comments could change at the same time and they are mixed, it would be a very hard task to be sure that only authorized changes were introduced.

Obviously now, when comment markers are stored in the content, one can change the comment marker positions, but these are the changes that the users are allowed to do in the editor anyway.

However, if you want to save your content together with comments data, check A simple “load and save” integration guide which should help you.

# When are the initial comments ready?

Depending on how the comments adapter is designed, initial comments can be loaded during the editor initialization or after it. Comment markers are added to the editor with the initial data but corresponding threads need to be downloaded separately.

To know when each marker added to the editor has a corresponding comment thread, use the observable state property which can have one of two values: loading or loaded.

const comments = editor.plugins.get( 'Comments' );

console.log( comments.state ); // Current state.

comments.on( 'change:state', ( name, value ) => {
    console.log( value );
    // When the state changes to `loaded` for the first time,
    // you can be sure that the initial comments are ready.
} );

The initial state is loading, but depending on the adapter it might be changed to loaded before or after the editor finishes its initialization.

# Theme customization

Using the power of CSS Variables it is really easy to override the default design of comments. This action can be done by adding an extra .css file.

CSS Variables in comments added to the document created in CKEditor 5 WYSIWYG editor.

The image above shows you which variables are responsible for every component of the comments sidebar.

# Example of comments customization with CSS Variables

With Inheritance of CSS Variables you can change the default :root values of variables in the .ck-sidebar scope. Adding these properties to your .css file or into the <head> section of the web page will override this plugin design.

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

/* Change the default yellow color of the comment marker in the content to green. */
:root {
    --ck-color-comments-marker: hsl(127, 98%, 83%);
    --ck-color-comments-marker-active: hsl(127, 98%, 68%);
}

.ck-sidebar {
    --ck-color-comments-background: #ecf5f0;
    --ck-color-comments-separator: #64ca6d;
    --ck-color-comments-remove-background: #eccbcb;

    --ck-color-comments-count: #807e81;

    --ck-color-comments-icon: #0f5c2f;
    --ck-color-comments-info: #1eb35c;

    --ck-comments-button-size: 0.85em;

    --ck-user-avatar-size: 35px;
    --ck-user-avatar-background: #239855;
}

/* You can even change the appearance of a single element. */
.ck-sidebar .ck-comment__wrapper:first-of-type {
    --ck-color-comments-info: #8e9822;
    --ck-user-avatar-background: #8e9822;
}

The examples above will generate the following comments designs:

Custom CSS Variables in comments added to the document created in CKEditor 5 WYSIWYG editor.