> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ably/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Message replies

Reply to messages that have been previously sent in the chat room.

Message replies are implemented using the `metadata` field when you [send a message](/docs/chat/rooms/messages#send).

## Send a reply

Use the [`metadata`](/docs/chat/rooms/messages#structure) field of a message to store the reply when you [send a message](/docs/chat/rooms/messages#send).

You need to at least include the `serial` of the parent message that you're replying to. Other information can be included such as a preview of the text:

```javascript theme={null}
async function sendReply(replyToMessage, replyText) {
  const metadata = {
    reply: {
      serial: replyToMessage.serial,
      timestamp: replyToMessage.timestamp.getTime(),
      clientId: replyToMessage.clientId,
      previewText: replyToMessage.text.substring(0, 140)
    }
  };

  await room.messages.send({
    text: replyText,
    metadata: metadata
  });
}
```

<Note>
  Ably achieves a global [median message delivery latency of 37ms](/docs/platform/architecture/latency#how-latency-is-measured), ensuring replies appear instantly across all participants.
</Note>

## Subscribe to message replies

Message replies will be received as normal messages in the room using the [`subscribe()`](/docs/chat/rooms/messages#subscribe) method.

You just need to handle storing and displaying the reply.

### Store reply information

When a user replies to a message, extract and store the parent message details:

```javascript theme={null}
function prepareReply(parentMessage) {
  return {
    serial: parentMessage.serial,
    timestamp: parentMessage.timestamp.getTime(),
    clientId: parentMessage.clientId,
    previewText: parentMessage.text.substring(0, 140)
  };
}
```

If a parent message isn't in local state, fetch it directly using its `serial`:

```javascript theme={null}
async function fetchParentMessage(replyData) {
  const message = await room.messages.get(replyData.serial);
  return message;
}
```

### Display replies

Check incoming messages for reply `metadata` and display accordingly:

```javascript theme={null}
room.messages.subscribe((messageEvent) => {
  const message = messageEvent.message;

  if (message.metadata?.reply) {
    const replyData = message.metadata.reply;
    const parentMessage = localMessages.find(msg => msg.serial === replyData.serial);

    if (parentMessage) {
      console.log(`Reply to ${parentMessage.clientId}: ${parentMessage.text}`);
    } else {
      console.log(`Reply to ${replyData.clientId}: ${replyData.previewText}`);
    }
  }

  console.log(`Message: ${message.text}`);
});
```

## Considerations

Consider the following when implementing message replies:

* Older messages may not be available depending on message persistence settings.
* Messages can be [updated](/docs/chat/rooms/messages#update), potentially removing references to replies.
* The `metadata` field is not server-validated.
* Nested replies can be complex and expensive to implement, so consider limiting reply depth.
