Report an issue

guideComments-only mode

The comments feature enables users to edit the rich-text document and add their comments.

In many applications, the document creation workflow consists of several precisely defined steps such as: content creation, discussion, proof-reading, final review and acceptance etc.

The users of such application may have certain roles and rights. This guide describes how to run the rich-text editor in the comments-only mode, where users are allowed to add and edit comments but not to change the document content. They are also unable to remove comment threads started by other authors.

Complementary to this guide, we provide a ready-to-use sample available for download. You may use the sample as an example or as a starting point for your own integration.

# Solution overview

Read-only mode comes to mind first when describing the above business need. However, in this use case the editor cannot be in the read-only mode as comments are handled through markers. Marker changes are treated in the same way as typing or any other content change. It means that it is not possible to add any comments in the standard read-only mode.

To support this usage scenario we provide the comments-only mode that enables the basic comment functionality (like creating, editing and removing threads and comments) and forbids any action that changes the content (like typing, drag & drop, pasting or cutting).

Note that if you use real-time collaborative comments, the editor will automatically switch to comments-only depending on the collaboration user roles. The following guide is for using comments without real-time collaboration.

# Enabling comments-only plugin

First, make sure that you correctly installed CKEditor 5 together with the comments plugin.

Then you should enable the comments-only mode. You can do it by setting the commentsOnly option in the editor configuration to true:

ClassicEditor.create( document.querySelector( '#editor' ), {
    licenseKey: 'your-license-key',
    commentsOnly: true,
    sidebar: {
        container: document.querySelector( '#sidebar' )
    }
    // ...
} );

You can also enable and disable the comments-only mode on demand by setting the value of the isEnabled property of the CommentsOnly plugin to true or false:

editor.plugins.get( 'CommentsOnly' ).isEnabled = true; // or false

Your code for the editor initialization should look similar to this if you are using a custom comments integration:

<!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>
        <p>
            <button id="comments-only-toggle">Toggle comments-only</button>
        </p>
        <div id="container">
            <div id="editor"></div>
            <div id="sidebar"></div>
        </div>
    </body>
    <script src="../build/ckeditor.js"></script>
    <script>
        // Application data will be available under a global variable `appData`.
        const appData = {
            // Users data.
            users: [
                {
                   id: 'user-1',
                   name: 'Joe Doe',
                   // Note that the avatar is optional.
                   avatar: 'https://randomuser.me/api/portraits/thumb/men/26.jpg'
                },
                {
                   id: 'user-2',
                   name: 'Ella Harper',
                   avatar: 'https://randomuser.me/api/portraits/thumb/women/65.jpg'
                }
            ],

            // The ID of the current user.
            userId: 'user-1',

            // Editor initial data.
            initialData:
                `<h2>
                    <comment id="thread-1" type="start"></comment>
                    Bilingual Personality Disorder
                    <comment id="thread-1" type="end"></comment>
                </h2>
                <p>
                    This may be the first time you hear about this made-up disorder but it actually isn’t so far from the truth.
                    As recent studies show, the language you speak has more effects on you than you realise.
                    According to the studies, the language a person speaks affects their cognition,
                    behaviour, emotions and hence <strong>their personality</strong>.
                </p>
                <p>
                    This shouldn’t come as a surprise
                    <a href="https://en.wikipedia.org/wiki/Lateralization_of_brain_function">since we already know</a>
                    that different regions of the brain becomes more active depending on the activity.
                    Since structure, information and especially <strong>the culture</strong> of languages varies substantially
                    and the language a person speaks is a essential element of daily life.
                </p>`
        };

        class CommentsAdapter {
            constructor( editor ) {
                this.editor = editor;
            }

            init() {
                const usersPlugin = this.editor.plugins.get( 'Users' );
                const commentsPlugin = this.editor.plugins.get( 'Comments' );

                // Load the users data.
                for ( const user of appData.users ) {
                    usersPlugin.addUser( user );
                }

                // Set the current user.
                usersPlugin.defineMe( appData.userId );

                // Set the adapter to the `Comments#adapter` property.
                commentsPlugin.adapter = {
                    addComment( data ) {
                        return Promise.resolve( {
                            createdAt: new Date()
                        } );
                    },

                    updateComment( data ) {
                        return Promise.resolve();
                    },

                    removeComment( commentId ) {
                        return Promise.resolve();
                    },

                    getCommentThread( threadId ) {
                        return Promise.resolve( {
                            threadId: 'thread-1',
                            comments: [
                                {
                                    commentId: 'comment-1',
                                    authorId: 'user-2',
                                    content: '<p>Are we sure we want to use a made-up disorder name?</p>',
                                    date: new Date()
                                }
                            ]
                        } );
                    }
                };
            }
        }

        ClassicEditor
            .create( document.querySelector( '#editor' ), {
                initialData: appData.initialData,
                extraPlugins: [ CommentsAdapter ],
                licenseKey: 'your-license-key',
                // Set the editor to the comments-only mode during the initialization.
                commentsOnly: true,
                sidebar: {
                    container: document.querySelector( '#sidebar' )
                },
                toolbar: {
                    items: [ 'bold', 'italic', '|', 'comment' ]
                }
            } )
            .then( () => {
                // Switch between the comments-only and editable mode when the user clicks the button.
                const button = document.querySelector( '#comments-only-toggle' );

                button.addEventListener( 'click', () => {
                    editor.plugins.get( 'CommentsOnly' ).isEnabled = !editor.plugins.get( 'CommentsOnly' ).isEnabled;
                } );
            })
            .catch( error => console.error( error ) );
    </script>
</html>

# Live demo

Check out the comments-only mode in action below!

# Security

Please remember that your application should be secured both on front-end and back-end. Even though the users will not be able to introduce their changes through the editor, you should still take care of preventing that in your back-end code.