User Lookup API

The TinyMCE User Lookup API allows you to retrieve and cache user details, such as names and avatars, and identify the current user within the editor.

This is useful when building features that rely on user context, such as commenting, collaborative editing, or displaying user-specific information. The API provides built-in caching for efficient user data management, as well as fallback user data when none is provided.

Properties and Methods

The User Lookup API serves two purposes, to identify the current user and to fetch user details for other users. These can be configured to suit your application through the user_id and fetch_users options respectively.

The User Lookup API provides properties and methods through the editor.userLookup object, which is available after the editor is initialized.

API Type Return Type

editor.userLookup.userId

Property

string

editor.userLookup.fetchUsers(userIds)

Method

Object<string, Promise<UserObject>>

editor.userLookup.userId

Returns the current user’s ID, set via the user_id configuration option. This is a string that uniquely identifies the user in the context of the editor, such as a username or an email address. If the user_id option is not set, it defaults to 'Anonymous'.

editor.userLookup.fetchUsers

Fetches and caches user information for the specified user IDs. This method accepts an array of user IDs and returns an object where each key is a user ID and each value is a Promise that resolves to the user object. If a user ID is not found, the Promise will reject with an error message.

The user object

The user is an Object that contains the following fields:

Field Type Required? Description

id

string

required

The unique string ID of the user.

name

string

optional

The display name of the user. If not provided, defaults to the id.

avatar

string

optional

The URL of the user’s avatar image or data URI. If not provided, an auto-generated SVG using the user’s initials will be used.

custom

Object

optional

Additional metadata for the user. This can include any custom fields relevant to your application, such as roles or permissions.

Example user object:
{
  id: 'user-1',           // Required: User identifier
  name: 'Jane Doe',       // Optional: Display name (defaults to id)
  avatar: 'https://...',  // Optional: Avatar URL or data URI
  custom: {               // Optional: Additional metadata
    role: 'admin',
    department: 'engineering'
  }
}

Options

The following configuration options affect the behavior of the User Lookup API.

user_id

This option sets the unique identifier for the current user in the editor. It is used in the the UserLookup API.

Type: String

Default value: 'Anonymous'

Example: using user_id option
tinymce.init({
  selector: 'textarea',  // Change this value according to your HTML
  user_id: 'alextaylor' // 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 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
tinymce.init({
  selector: '#editor',
  user_id: 'alextaylor',
  fetch_users: (userIds) => Promise.all(userIds
    .map((userId) =>
      fetch(`/users/${userId}`) // Fetch user data from the server
      .then((response) => response.json())
      .catch(() => ({ id: userId })) // Still return a valid user object even if the fetch fails
  )),
});
Example: returning user array with validation
tinymce.init({
    selector: '#editor',
    user_id: 'alextaylor',
    fetch_users: async (userIds) => {
        const users = await fetch('/users', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ userIds })
        })
        .then((response) => response.json())
        .catch(() =>
            userIds.map((userId) =>
                ({ id: userId }) // Still returns valid users even if the fetch fails
            )
        );

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

Usage Examples

Basic setup

For a basic setup, configuring the user_id option allows you to identify the current user. The fetch_users option can be omitted, and TinyMCE will provide fallback user data.

tinymce.init({
  selector: '#editor',
  user_id: 'alextaylor'
});

Complete setup with fetch_users

This example demonstrates how to simulate user lookup in-browser. In a production environment, the fetch_users function would typically make network requests to your backend API.

Example
const userDb = {
  'janedoe': {
    id: 'janedoe',
    name: 'Jane Doe',
    avatar: 'https://example.com/avatar/jane.png'
  },
  'johnsmith': {
    id: 'johnsmith',
    name: 'John Smith'
  },
  'alextaylor': {
    id: 'alextaylor',
    name: 'Alex Taylor',
    avatar: 'https://example.com/avatar/alex.png'
  }
};

tinymce.init({
  selector: '#editor',
  user_id: 'alextaylor',
  fetch_users: (userIds) => {
    return Promise.all(
      userIds.map(
        (userId) => new Promise(
          (resolve) => resolve(userDb[userId] || { id: userId }) // Return user data or a fallback object if not found
        )
      )
    )
  },
});
It is recommended to handle (or catch) promise rejections in the fetch_users function by providing fallback data. This will ensure that your application can gracefully handle cases where user data is not found or the network request fails.

Basic usage

Once the editor is initialized, you can access the current user ID and fetch user information:

editor.on('init', () => {
  // Get the current user ID
  const currentUserId = editor.userLookup.userId;
  console.log('Current user:', currentUserId);

  // Fetch user information
  const users = editor.userLookup.fetchUsers([ currentUserId ]);

  users[currentUserId].then((user) => {
    console.log('Current user name:', user.name);
  });

  // Handle multiple users
  Promise.all(Object.values(users)).then((allUsers) => {
    allUsers.forEach((user) => {
      console.log(`Fetched: ${user.name} (${user.id})`);
    });
  });
});

Advanced usage with UI example

This example shows how to create a toolbar button that displays the current user’s information:

tinymce.init({
  selector: '#editor',
  user_id: 'alextaylor',
  setup: (editor) => {
    editor.ui.registry.addButton('show-user', {
      text: 'Show User',
      onAction: () => {
        const currentUser = editor.userLookup.userId;
        const users = editor.userLookup.fetchUsers([ currentUser ]);

        users[currentUser].then((user) => {
          editor.notificationManager.open({
            text: `Logged in as: ${user.name}`,
            type: 'info'
          });
        });
      }
    });
  },
  toolbar: 'show-user'
});

Fallback Behavior

If no fetch_users function is configured, TinyMCE will return fallback users with auto-generated data:

  • name defaults to the user ID

  • avatar is an auto-generated SVG using the first letter of the name

This is useful for simpler setups or prototyping:

tinymce.init({
  selector: '#editor',
  user_id: 'alextaylor'
});

editor.on('init', () => {
  const users = editor.userLookup.fetchUsers(['alextaylor']);
  users['alextaylor'].then((user) => {
    console.log('Generated fallback user:', user);
  });
});