---
title: "Configuring the Comments plugin in embedded mode"
description: "Information on configuring the Comments plugin in embedded mode"
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/comments-embedded-mode/"
md_url: "https://www.tiny.cloud/docs/tinymce/latest/comments-embedded-mode/index.md"
version: "latest"
last_updated: "2026-08-31T06:13:46Z"
tokens: 3124
---
# Configuring the Comments plugin in embedded mode

## Add the Comments plugin in embedded mode

To add the Comments plugin in embedded mode to the TinyMCE, configure the following options:

```js
const userDb = {
  'author': {
    id: 'author',
    name: 'Name of the commenter',
    avatar: 'https://example.com/avatar/john.png'
  },
};

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  user_id: 'author',
  fetch_users: (userIds) => {
    return Promise.all(
      userIds.map(
        (userId) => new Promise(
          (resolve) => resolve(userDb[userId] || { id: userId })
        )
      )
    )
  },
  tinycomments_mode: 'embedded'
});
```
This is the minimum recommended setup for the Comments plugin in embedded mode. If the `user_id` or `tinycomments_author` options are not configured, all users will be assigned the name " *ANON* ".

## Interactive example

**Example**

```js
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

const user_id = 'james-wilson';

const tinycomments_can_resolve = (req, done, _fail) => {
  const allowed = req.comments.length > 0 && req.comments[0].author === author;
  done({ canResolve: allowed });
};

tinymce.init({
  selector: 'textarea#comments-embedded',
  plugins: [ 'tinycomments', 'help', 'code', 'quickbars', 'link', 'lists', 'image' ],
  toolbar: 'addcomment showcomments code | bold italic underline',
  menubar: 'file edit view insert format tools tc',
  menu: {
    tc: {
      title: 'Comments',
      items: 'addcomment showcomments deleteallconversations'
    }
  },
  quickbars_selection_toolbar: 'alignleft aligncenter alignright | addcomment showcomments',
  quickbars_image_toolbar: 'alignleft aligncenter alignright | rotateleft rotateright | imageoptions',

  tinycomments_mode: 'embedded',
  sidebar_show: 'showcomments',
  tinycomments_can_resolve,
  
  user_id,
  fetch_users: (userIds) => Promise.all(userIds
    .map((userId) =>
      fetch(`${API_URL}/${userId}`)
        .then((response) => response.json())
        .catch(() => ({ id: userId }))))
});
```

## Options

### `user_id`

This option sets the unique identifier for the current user in the editor. It is used in the the [`UserLookup`](../userlookup/) API.

**Type:** `String`

**Default value:** `'Anonymous'`

Example: using `user_id` option
```javascript
tinymce.init({
  selector: 'textarea',  // Change this value according to your HTML
  user_id: 'james-wilson' // replace this with a unique string to identify the user
});
```

### `fetch_users`

A **required callback function** that fetches user data. This function is called with an array of user IDs and should return a `Promise` that resolves to an array of user objects. The callback is used by the [`UserLookup`](../userlookup/) API. If the returned array does not include all requested user IDs, promises for the missing users will be rejected with a "User {id} not found" error.

**Type:** `Function`

**Parameters:** - `ids` (`Array<string>`): An array of user IDs to fetch.

**Returns:** - `Promise<Array<Object>>`: A promise that resolves to an array of user objects.

Example: using `fetch_users` option
```javascript
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

tinymce.init({
  selector: 'textarea',
  user_id: 'james-wilson',
  fetch_users: (userIds) => Promise.all(userIds
    .map((userId) =>
      fetch(`${API_URL}/${userId}`)
        .then((response) => response.json())
        .catch(() => ({ id: userId })))),
});
```
Example: returning user array with validation
```javascript
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';

tinymce.init({
  selector: 'textarea',
  user_id: 'james-wilson',
  fetch_users: async (userIds) => {
    const users = await Promise.all(userIds
        .map((userId) =>
        fetch(`${API_URL}/${userId}`)
            .then((response) => response.json())
            .catch(() => ({ id: userId }))));

    return userIds.map(
      (userId) =>
        users.find((user) => user.id === userId)
        || ({ id: userId }) // Still returns a valid user even if it wasn't returned from the server
    );
  },
});
```

### `tinycomments_author`

> **Important:** This option has been deprecated in TinyMCE 8 and may be removed in a future major TinyMCE release. Use a combination of `user_id` and `fetch_users` instead. | `User Lookup API`
This option sets the author id to be used when creating or replying to comments.

**Type:** `String`

**Default value:** `'Anon'`

#### Example: using `tinycomments_author`

```js
tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  tinycomments_mode: 'embedded',
  tinycomments_author: 'embedded_journalist',
});
```

### `tinycomments_author_avatar`

> **Important:** This option has been deprecated in TinyMCE 8 and may be removed in a future major TinyMCE release. Use a combination of `user_id` and `fetch_users` instead. | `User Lookup API`
*Optional*: This option sets the URL for the author’s avatar to be used when creating or replying to comments. If this option is omitted, a generated avatar will be used instead. The avatar, if provided:

- will be scaled to a 36px diameter circle; and
- can be any filetype able to be wrapped in an `<img>` element.

> **Important:** The avatar will be stored alongside the embedded comment data when a new comment is created and cannot be changed later by changing this options value. To change the avatar image, the image on the server that the URL points to should be updated instead.
**Type:** `String`

#### Example: using `tinycomments_author_avatar`

```js
tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  tinycomments_mode: 'embedded',
  tinycomments_author: 'embedded_journalist',
  tinycomments_author_name: 'Embedded Journalist',
  tinycomments_author_avatar: 'https://example.com/image.ext'
});
```

### `tinycomments_author_name`

> **Important:** This option has been deprecated in TinyMCE 8 and may be removed in a future major TinyMCE release. Use a combination of `user_id` and `fetch_users` instead. | `User Lookup API`
*Optional*: This option sets the author’s display name to be used when creating or replying to comments. If this option is omitted, the author `id` is used instead.

**Type:** `String`

#### Example: using `tinycomments_author_name`

```js
tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  tinycomments_mode: 'embedded',
  tinycomments_author: 'embedded_journalist',
  tinycomments_author_name: 'Embedded Journalist',
});
```

### `tinycomments_can_delete`

*Optional*: This option sets the author permissions for *deleting comment conversations*. If the `tinycomments_can_delete` option is **not included**, the current author (`user_id`) cannot delete comment conversations created by other authors.

**Type:** `Function`

**Default value:**

```js
(req, done, fail) => {
  const allowed = req.comments.length > 0 && req.comments[0].author === <Current_user_id>;
  done({
    canDelete: allowed
  });
}
```

> **Note:** The following example extends the default behavior to allow the author `<Admin user>` to delete other author’s comment conversations by adding `|| currentAuthor === '<Admin user>'`.

#### Example: using `tinycomments_can_delete`

```js
const currentAuthor = 'embedded_journalist';

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  tinycomments_mode: 'embedded',
  user_id: currentAuthor,
  tinycomments_can_delete: (req, done, fail) => {
    const allowed = req.comments.length > 0 && req.comments[0].author === currentAuthor;
    done({
      canDelete: allowed || currentAuthor === '<Admin user>'
    });
  }
});
```

### `tinycomments_can_resolve`

*Optional*: This option adds a *Resolve Conversation* item to the dropdown menu of the first comment in a conversation. This callback sets the author permissions for *resolving comment conversations*.

**Type:** `Function`

#### Example: using `tinycomments_can_resolve`

```js
const currentAuthor = 'embedded_journalist';

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  tinycomments_mode: 'embedded',
  user_id: currentAuthor,
  tinycomments_can_resolve: (req, done, fail) => {
    const allowed = req.comments.length > 0 && req.comments[0].author === currentAuthor;
    done({
      canResolve: allowed || currentAuthor === '<Admin user>'
    });
  }
});
```

### `tinycomments_can_delete_comment`

*Optional*: This option sets the author permissions for *deleting comments*. If the `tinycomments_can_delete_comment` option is **not included**, the current author (`user_id`) **cannot** delete comments added by other authors.

**Type:** `Function`

**Default value:**

```js
(req, done, fail) => {
  const allowed = req.comment.author === <Current_user_id>;
  done({
    canDelete: allowed
  });
}
```

> **Note:** The following example extends the default behavior to allow the author `<Admin user>` to delete other author’s comments by adding `|| currentAuthor === '<Admin user>'`.

#### Example: using `tinycomments_can_delete_comment`

```js
const currentAuthor = 'embedded_journalist';

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  tinycomments_mode: 'embedded',
  user_id: currentAuthor,
  tinycomments_can_delete_comment: (req, done, fail) => {
    const allowed = req.comment.author === currentAuthor;
    done({
      canDelete: allowed || currentAuthor === '<Admin user>'
    });
  }
});
```

### `tinycomments_can_edit_comment`

*Optional*: This option sets the author permissions for *editing comments*. If the `tinycomments_can_edit_comment` option is **not included**, the current author (`user_id`) cannot edit comments added by other authors.

**Type:** `Function`

**Default value:**

```js
(req, done, fail) => {
  const allowed = req.comment.author === <Current_user_id>;
  done({
    canEdit: allowed
  });
}
```
The following example extends the default behavior to allow the author `<Admin user>` to edit other author’s comments by adding `|| currentAuthor === '<Admin user>'`.

#### Example: using `tinycomments_can_edit_comment`

```js
const currentAuthor = 'embedded_journalist';

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  tinycomments_mode: 'embedded',
  user_id: currentAuthor,
  tinycomments_can_edit_comment: (req, done, fail) => {
    const allowed = req.comment.author === currentAuthor;
    done({
      canEdit: allowed || currentAuthor === '<Admin user>'
    });
  }
});
```

### `tinycomments_always_show_highlights`

*Optional*: The Comments plugin offers the `tinycomments_always_show_highlights` option to keep the highlighting on commented content visible while the Comments sidebar is closed. By default, TinyMCE highlights commented content only while the sidebar is open, and removes the highlighting from the editor content once the sidebar is closed.

When this option is set to `true`, TinyMCE highlights commented content whether the sidebar is open or closed, and selecting highlighted content reopens the closed Comments sidebar.

**Type:** `Boolean`

**Default value:** `false`

**Possible values:** `true`, `false`

#### Example: using `tinycomments_always_show_highlights`

```js
const currentAuthor = 'embedded_journalist';

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  toolbar: 'addcomment showcomments',
  tinycomments_mode: 'embedded',
  user_id: currentAuthor,
  tinycomments_always_show_highlights: true
});
```

## Show sidebar on editor load

The [`sidebar_show`](../customsidebar/#sidebar_show) option can be used to show the Comments sidebar when the editor is loaded.

For example:
```js
tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'tinycomments',
  tinycomments_mode: 'embedded',
  user_id: currentAuthor,
  tinycomments_can_resolve: canResolveCommentsCallback,
  sidebar_show: 'showcomments'
});
```

## Configuring the commented text and block CSS properties

The highlight styles are now a part of the overall content skin and are changed through customizing the skin.

TinyMCE open source project [oxide](https://github.com/tinymce/oxide/blob/master/src/less/theme/content/comments/comments.less) (default skin), defines the variables used for changing the annotation colors.

Refer to the [documentation](../creating-a-skin/) for building a skin using this repo.

For more information on configuring TinyMCE formats, refer to the [formats](../content-formatting/#formats) section.
