# Users

The [`Users`](../../api/module_collaboration-core_users-Users.md) plugin and related plugins let you manage user data and permissions. This is essential when many users are working on the same document.

<a id="additional-feature-information">

## Additional feature information

The users plugin is automatically provided if you load any collaboration features plugins.

You must set the users data before you load the collaboration features. To do that, create a plugin that requires all collaboration features you use and defines the users.

```js
// An example of a plugin that provides user data for an editor
// that uses the `Comments` and `RevisionHistory` plugins.
class UsersIntegration extends Plugin {
	static get requires() {
		return [ 'Comments', 'RevisionHistory' ];
	}

	init() {
		const users = this.editor.plugins.get( 'Users' );

		// Provide user data from your database.
		users.addUser( {
			id: 'u1',
			name: 'Zee Croce'
		} );

		users.addUser( {
			id: 'u2',
			name: 'Mex Haddox'
		} );

		// Define the local user.
		users.defineMe( 'u1' );
	}
}

// More code.
// ...

ClassicEditor
	.create( {
		extraPlugins: [ UsersIntegration ],
		// More editor's configuration.
		// ...
	} );
```

> **Note**
>
> For real-time collaboration applications, users are set and managed automatically by the real-time collaboration plugins and the Cloud Services server, hence you should not use the permissions API.
>
> The real-time collaborative editing plugin will define user data and permissions automatically based on [your token data](../../../../cs/latest/developer-resources/security/token-endpoint.md#user).

<a id="local-user-me-user">

## Local user (“me” user)

A local user (also called “me” user) is regarded as the one who uses the editor instance. Features (like comments or revisions history) will attribute changes to that user.

You can access the “me” user via `Users` plugin:

```js
const usersPlugin = editor.plugins.get( 'Users' );

	// We get either `User` or `undefined` if the local user is not set.
	const localUser = usersPlugin.me;
```

You can also use the `isMe` flag on the `User` item to check if it is the local user:

```js
const id = 'e1d1a156789abc92e4b9affff124455bb';
	const user = editor.plugins.get( 'Users' ).getUser( id );

	// It is `true` if it is the "me" user, `false` otherwise.
	const isOwnUser = user.isMe;
```

The local user’s avatar is highlighted in all places it is displayed. You can easily override this behavior using the `.ck-user_me` CSS class selector.

```css
/* Display the local user the same as other users. */
	.ck-user.ck-user_me {
		border: none;
		outline: none;
	}
```

<a id="anonymous-user">

## Anonymous user

If for some reason you do not want to, or you cannot, provide the user data, you can use the anonymous user:

```js
const usersPlugin = editor.plugins.get( 'Users' );

usersPlugin.useAnonymousUser();

usersPlugin.me.name; // 'Anonymous'
usersPlugin.me.id; // 'anonymous-user'
```

The anonymous user’s avatar is a contour of a human face.

You can set the anonymous user’s ID using the `config.users.anonymousUserId` property:

```js
ClassicEditor
	.create( {
		// More editor's configuration.
		// ...
		users: {
			anonymousUserId: '0'
		}
	} );
```

<a id="user-permissions">

## User permissions

In many applications, the document creation workflow consists of several precisely defined steps such as content creation, discussion, proofreading, final review and acceptance, etc. The users of such an application may have certain roles and permissions.

You can change the permissions for a given user, which results in enabling or disabling some editor functionalities.

> **Note**
>
> For real-time collaboration applications, refer to the [Roles and permissions](../../../../cs/latest/developer-resources/security/roles.md) guide in the Cloud Services documentation.

You can set the permissions using the [`Permissions`](../../api/module_collaboration-core_permissions-Permissions.md) plugin. It is automatically provided if you load any of the collaboration features plugins.

It is a good practice to set permissions directly after defining the users:

```js
class UsersIntegration extends Plugin {
	// More methods.
	// ...

	init() {
		const users = this.editor.plugins.get( 'Users' );

		// Provide user data from your database.
		users.addUser( {
			id: 'u1',
			name: 'Zee Croce'
		} );

		users.addUser( {
			id: 'u2',
			name: 'Mex Haddox'
		} );

		// Define the local user.
		users.defineMe( 'u1' );

		// Set permissions.
		const permissions = this.editor.plugins.get( 'Permissions' );

		// "Commentator" role.
		permissions.setPermissions( [
			'comment:write'
		] );
	}
}
```

The full list of defined permissions is available in the [`Permissions`](../../api/module_collaboration-core_permissions-Permissions.md) plugin description.

> **Note**
>
> You should secure your application both on the frontend and backend. Even though the users will not be able to do some actions through the editor, you should still take care of securing incoming data in your backend code.

<a id="operation-authors">

## Operation authors

The [`Users#getOperationAuthor()`](../../api/module_collaboration-core_users-Users.md#function-getOperationAuthor) method gives you the ability to check which user created a given operation. This is useful when creating custom features in integrations using [real-time collaboration](real-time-collaboration/real-time-collaboration.md).

There are two cases when the operation author might be `null`:

1. For initial operations (fetched from the server when connecting).
2. For some automatically created operations that are not meaningful (`NoOperation`s).

Below is an example of using `getOperationAuthor()` to find out which user was the last to edit the document. In this case, you should skip `NoOperation`s and some `MarkerOperation`s since they do not affect the document content.

```js
let lastUser = null;

editor.model.on( 'applyOperation', ( evt, args ) => {
	const users = editor.plugins.get( 'Users' );
	const operation = args[ 0 ];

	if ( operation.isDocumentOperation && affectsData( operation ) ) {
		const user = users.getOperationAuthor( operation );

		if ( user && user != lastUser ) {
			lastUser = user;

			console.log( lastUser.name, lastUser, operation );
		}
	}

	function affectsData( operation ) {
		return operation.type != 'noop' && ( operation.type != 'marker' || operation.affectsData );
	}
} );
```

<a id="customize-initials">

## Customize initials

To customize how [`user initials`](../../api/module_collaboration-core_users-User.md#member-initials) are generated, set the [`getInitialsCallback`](../../api/module_collaboration-core_config-CollaborationUsersConfig.md#member-getInitialsCallback) configuration option when initializing the editor:

```js
ClassicEditor
	.create( {
		// More editor's configuration.
		// ...
		users: {
			getInitialsCallback: ( name: string ) => {
				// Custom logic to generate initials.
				return name.split( ' ' )[ 0 ].charAt( 0 ) + name.split( ' ' )[ 1 ].charAt( 0 );
			}
		}
	} );
```

<a id="theme-customization">

## Theme customization

<a id="user-avatar">

### User avatar

You can define the user’s avatar appearance by modifying these CSS variables:

```css
:root {
	--ck-user-avatar-size: 40px;
	--ck-user-avatar-background: hsl(210, 52%, 44%);
	--ck-user-name-color: hsl(0, 0%, 100%);

	/* Border color used to highlight the local user. */
	--ck-user-me-border-color: hsl(0, 0%, 100%);
}
```

<a id="user-colors">

### User colors

You can also define colors used to represent the selection of other users.

User colors are defined using [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables). There are 8 user colors defined by default. You can add more colors or change the default colors.

Color variables with an alpha channel (`--ck-user-colors--$(number)-alpha`) are used for selection highlights. The solid color variables (`--ck-user-colors--$(number)`) are used in the rest of the user UI elements. You are welcome to change this color palette to fit your UI.

```css
/* The current color set for users in the collaboration plugins. */
:root {
	--ck-user-colors--0: hsla(235, 73%, 67%, 1);
	--ck-user-colors--0-alpha: hsla(235, 73%, 67%, 0.15);

	--ck-user-colors--1: hsla(173, 100%, 24%, 1);
	--ck-user-colors--1-alpha: hsla(173, 100%, 24%, 0.15);

	--ck-user-colors--2: hsla(0, 46%, 50%, 1);
	--ck-user-colors--2-alpha: hsla(0, 46%, 50%, 0.15);

	--ck-user-colors--3: hsla(256, 54%, 45%, 1);
	--ck-user-colors--3-alpha: hsla(256, 54%, 45%, 0.15);

	--ck-user-colors--4: hsla(95, 50%, 36%, 1);
	--ck-user-colors--4-alpha: hsla(95, 50%, 36%, 0.15);

	--ck-user-colors--5: hsla(336, 78%, 43%, 1);
	--ck-user-colors--5-alpha: hsla(336, 78%, 43%, 0.15);

	--ck-user-colors--6: hsla(0, 80%, 59%, 1);
	--ck-user-colors--6-alpha: hsla(0, 80%, 59%, 0.15);

	--ck-user-colors--7: hsla(184, 90%, 43%, 1);
	--ck-user-colors--7-alpha: hsla(184, 90%, 43%, 0.15);
}
```

These colors are, among others, used in the [users presence list](real-time-collaboration/users-in-real-time-collaboration.md#users-presence-list) to represent users.

<a id="adding-more-user-colors">

### Adding more user colors

You can define additional colors for users if you find the default set too small.

First, prepare a CSS file with some color definitions:

```css
/* mycolors.css */

:root {
	--ck-user-colors--8: hsla(31, 90%, 43%, 1);
	--ck-user-colors--8-alpha: hsla(31, 90%, 43%, 0.15);

	--ck-user-colors--9: hsla(61, 90%, 43%, 1);
	--ck-user-colors--9-alpha: hsla(61, 90%, 43%, 0.15);
}
```

Then, import this CSS file and specify the `colorsCount` configuration option:

```js
import './mycolors.css';

ClassicEditor
	.create( {
		// More editor's configuration.
		// ...
		users: {
			colorsCount: 10
		}
	} );
```

---

Full index of the CKEditor 5 documentation: [llms.txt](../../../llms.txt)
