🎉 New! Integrate Beams with Chatkit for powerful push notifications—find out more

Extensible API for in-app chat


Build scalable realtime features


Programmatic push notifications



Read the docs to learn how to use our products


Explore our tutorials to build apps with Pusher products


Reach out to our support team for help and advice

Sign in
Sign up

Top five Chatkit instant messaging features

  • Abati Adewale

December 3rd, 2018
Some knowledge of React will help with understanding the code samples.

In this tutorial, we will discuss top five messaging features that you can add to your apps. Examples are written in React. First though, we will discuss briefly what Chatkit is.

Messaging in apps is a feature that is now necessary in most applications. The ability for a user to interact with an admin or with others using an app makes the experience even more delightful. While this is great for the user, integrating messaging features in an app might be an undesired burden to the developer. However, thanks to Pusher’s Chatkit, integrating messaging features can be straightforward too for the developer.


Chatkit is designed to make it easy to add chat to your app. It goes beyond the core features of any chat, such as creating rooms, users and messages. It also includes features like:

  • Private and public rooms - Control which users have access to a room.
  • Presence updates - Get updated when users change their online/offline status.
  • Files - Upload and download files from rooms and attach them to your messages.
  • Permission system - Flexible control on what users can do and access.
  • Typing indicators - Receive events when users start or stop typing in rooms.
  • Read cursors - Keep track of the most recently read message ID for each member of a room

Let us go on to discuss some of the top five Chatkit features, the impact they will have on the user experience and how they can be integrated in any React app.

For a more detailed discussion of how Chatkit can be added to your React application, refer to this article on How to build a realtime messaging feature in React Apps with Chatkit.

Roles and permissions

In many chat applications, all users cannot perform all actions that are allowed in that application. For instance, in some chat apps, not all users have the ability to use certain features like adding or removing a user in a room or calling the attention of all users. These permissions are allowed based on a person’s role. Users are assigned roles that determine the actions they can do or cannot do. Roles make it possible to easily control the access a user has to certain features of the app. A Chatkit instance comes with two default roles – default and admin.

The admin role is allowed to perform any action while the default role is restricted in the number of actions it can perform. Chatkit also makes it possible to change the user roles if it is needed. All you need to do is to send a request to the Chatkit servers with the user ID and the new role you want the user to have.

The next big question is: how does Chatkit recognize the actions a user can perform in the app? Here is how it works under the hood.

When a user makes a request to the Chatkit servers, a JSON Web Token(JWT) accompanies the request. It is from this token that the ID of the user is extracted and this is used to extract the roles of the user and actions they can perform. The request of the user is then compared against the actions that they can perform in the role they have and if their request will be permitted or denied. Let us consider some of these permissions.

Different permissions are available to different roles. In Chatkit, there are room scoped permissions and globally scoped permissions.

For room scoped permissions, some permissions are adding a new member to a room, removing existing members from the room, deleting the room, updating the room and adding messages to the room. For the globally scoped permissions, some permissions are if the user can join any public room, if the user can update their own user entity, user can get information about any user, user can get information about any room.

Chatkit makes it possible to integrate all of this very easily in your React chat app.

Presence updates

Presence updates are important for messaging. It helps the user to know if the user on the other end of the chat is online or offline. This improves the experience of the user as the user will not need to wait endlessly for a response to a sent message. Chatkit makes it easy to update the presence of a user.

In Chatkit, if the user has at least one active connection to any of Chatkit’s service , the user is consider online. If there is no active connection, the user is considered offline. The presence property of the user object is used to determine when the user is offline or online.

For instance, if we need to perform an action when a user is online, using JavaScript, we can do this.

    if (user.presence.state === 'online') {
      console.log('I am online');

However, to be able to perform actions when the user comes online or goes offline, we need to add a presence hook to each user.

    onUserCameOnline: (user) => {
      console.log(`User ${user.name} came online`)
    onUserWentOffline: (user) => {
      console.log(`User ${user.name} went offline`)

Even more than this, we can have little circles by the side of the name of a user to indicate when the user is offline or online as it is done in apps like Slack or even state it like it is done in apps like WhatsApp. Chatkit makes doing all of these things easy.

Typing indicators

Typing indicators are another useful feature you can add to your messaging app in React. This helps a connected user to know when another user in a room is typing. It makes the messaging more interactive and fun. Of course, Chatkit makes it easy to integrate this feature in your chat app.

There are two parts to make this feature work in your React app. The first part is to trigger a typing event. To do this, we need to call the isTypingIn method which is part of the user object with the ID of the room the user is typing in.

For instance, in the chat component, we can add a typing method that triggers this action.

    sendTypingEvent() {
        .isTypingIn({ roomId: this.state.currentRoom.id })
        .catch(error => console.error('error', error))

The second part of this is adding it to the room hooks of that room to receive typing notification events. This way every user in the room can see when another user is typing. To do this, we use two functions: onUserStartedTyping and a onUserStoppedTyping like the example below. This way when the user starts or stops typing, it will be indicated in the room.

    onUserStartedTyping: user => {
      console.log(`User ${user.name} started typing`)
    onUserStoppedTyping: user => {
      console.log(`User ${user.name} stopped typing`)


One feature that makes messaging more exciting is the ability to send and receive files. Whether this files are PDFs, images or in other forms, users want to be be able to conveniently share files with other users. Chatkit makes this easy to do.

In Chatkit, it is possible to attach files to messages. If a message has an attachment, the user will have to fetch it to use it. Doing this will give you the actual URL of the resource. There are three attributes of attachments done with Chatkit. These are:

  • link which represents the URL of the file and where it can be found
  • type which indicates the type of attachment if it is an image, a video, audio or a text file
  • fetchRequired which is a boolean and determines if the file needs to be fetched from the Chatkit servers.

To fetch an attachment, if fetchRequired is set to false, then the attachment link can be used to fetch the attachment directly. Otherwise, the attachment link cannot be used directly and we must fetch the URL of the attachment using fetchAttachment.

Below is an example of how this can be done:

    currentUser.fetchAttachment({ url: attachment.link })
      .then(url => {
        // do something with the url
      .catch(err => {
        console.log('Error fetching attachment:', err)

Read cursors

Adding read cursors to your messaging app can help to provide a better user experience for users. This way the users will be able to keep track of how far they have read through the messages in a chat room and thus help them keep track of unread messages in the room. It is also good for other users to know how many members in the room have read a sent message. Chatkit makes this quite easy too.

In Chatkit, each read cursor belongs to a user and a room and it is represented by a cursor object. This cursor object has the following properties.

  • The cursor position: that indicates the message id the user has read up to
  • updatedAt : that indicates the timestamp when the cursor was last set
  • room : the room where the read cursor was set
  • user: the user that has the cursor object
  • type: the type of the cursor object, currently always 0 (representing a read cursor).

Let us now see how we can use this cursor object.

First, we need to set a user cursor. This should be done when we are sure that the user has read at least one message in the room. To do this, we call the setReadCursor and then pass the roomId and a position which is the ID of the newest message that has been read. This is done as follows:

      roomId: someRoomId,
      position: someMessageId
      .then(() => {
      .catch(err => {
        console.log(`Error setting cursor: ${err}`)

Once this is done, we can easily access these cursors by getting the read cursors. To get the read cursors, we do use the readCursor method. If the cursor has not been set, it returns undefined. To do this, we can do the following:

    const cursor = currentUser.readCursor({
      roomId: someRoomId
    console.log(`read up to message ID ${
    } in ${

It is also possible for a user in a room to access another user’s read cursor. To do this, the user supplies the userId as a second parameter to the readCursor method like the example below.

    const alicesCursor = currentUser.readCursor({
      roomId: someRoomId,
      userId: 'alice'
    console.log(`Alice has read up to ${
    } in ${

To be notified when any member of a room changes their read cursor, a onNewReadCursor hook is supplied when subscribing to a room.


Using Chatkit, the above are some of the features you can add to messaging in your app to give the user an even more delightful experience. The best part is that Chatkit makes this all easy and straightforward to add to your app.

  • Chat
  • JavaScript
  • Online Presence
  • React
  • Social Interactions
  • Social
  • Chatkit


  • Channels
  • Chatkit
  • Beams

© 2020 Pusher Ltd. All rights reserved.

Pusher Limited is a company registered in England and Wales (No. 07489873) whose registered office is at 160 Old Street, London, EC1V 9BW.