Skip to content

Support read receipts in your app built with XMTP

Use the read receipt content type to support read receipts in your app. A read receipt is a timestamp that indicates when a message was read. It is sent as a message and can be used to calculate the time since the last message was read.

Provide an opt-out option

While this is a per-app decision, the best practice is to provide users with the option to opt out of sending read receipts. If a user opts out, when they read a message, a read receipt will not be sent to the sender of the message.

Configure the content type

For Browser SDK (v6.0.0+) and Node SDK (v5.0.0+), read receipts are built-in and do not require codec registration. Skip this step for these SDKs.

For other SDKs, register the codec:

React Native
const client = await Client.create(signer, {
  env: 'production',
  codecs: [new ReadReceiptCodec()],
});

Send a read receipt

Browser
// Send a read receipt
await conversation.sendReadReceipt();

Receive a read receipt

Here's how you can receive a read receipt:

Browser
// the browser SDK does not return read receipts when reading messages
// to see the last read timestamp for inboxes in a conversation, use the `lastReadTimes` method
 
const lastReadTimes = await conversation.lastReadTimes();
lastReadTimes.get(recipientInboxId); // the last read timestamp in nanoseconds for the inbox
 
// note: if the last read timestamp is undefined, the inbox has not sent a read receipt yet

Get last read times

Get the timestamp of when each participant last read the conversation:

React Native
// React Native doesn't have a getLastReadTimes() convenience method.
// Track read receipts manually by filtering messages:
const messages = await conversation.messages();
const readReceipts = messages.filter(
  (msg) => msg.contentTypeId === 'xmtp.org/readReceipt:1.0'
);
 
// Build a map of last read times by sender
const lastReadTimes = new Map<string, Date>();
readReceipts.forEach((receipt) => {
  const existing = lastReadTimes.get(receipt.senderInboxId);
  if (!existing || receipt.sent > existing) {
    lastReadTimes.set(receipt.senderInboxId, receipt.sent);
  }
});

Display a read receipt

ReadReceipts have an undefined or nil fallback, indicating the message is not expected to be displayed. To learn more, see Handle unsupported content types section.

Notifications and read receipts

Read receipts have shouldPush set to false, which means that read receipts do not trigger push notifications as long as the notification server respects this flag.

Use a read receipt

Generally, a read receipt indicator should be displayed under the message it's associated with. The indicator can include a timestamp. Ultimately, how you choose to display a read receipt indicator is completely up to you.

The read receipt is provided as an empty message whose timestamp provides the data needed for the indicators. Be sure to filter out read receipt empty messages and not display them to users.

You can use a read receipt timestamp to calculate the time since the last message was read. While iterating through messages, you can be sure that the last message was read at the timestamp of the read receipt if the string of the timestamp is lower.