> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-rn-guide-message-privately.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Threaded Messages

> Send, receive, and fetch threaded messages with the CometChat JavaScript SDK.

Messages that are started from a particular message are called Threaded messages or simply threads. Each Thread is attached to a message which is the Parent message for that thread.

## Send Message in a Thread

Any message type (Text, Media, or Custom) can be sent in a thread. Set the `parentMessageId` using `setParentMessageId()` to indicate which thread the message belongs to.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    let receiverId = "UID",
      receiverType: string = CometChat.RECEIVER_TYPE.USER,
      textMessage: CometChat.TextMessage = new CometChat.TextMessage(receiverId, "Hello", receiverType),
      messageId: number = 100;

    textMessage.setParentMessageId(messageId);

    CometChat.sendMessage(textMessage).then(
    (message: CometChat.TextMessage) => {
    console.log('Message sent successfully', message);
    }, (error: CometChat.CometChatException) => {
    console.log('Message sending failed', error);
    }
    );

    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    let UID = "UID";
    let textMessage = new CometChat.TextMessage(UID, "Hello", CometChat.RECEIVER_TYPE.USER);
    textMessage.setParentMessageId(100);

    CometChat.sendMessage(textMessage).then(
      message => {
          console.log('Message sent successfully', message);
      }, err => {
          console.log('err', err);
      }
    )
    ```
  </Tab>
</Tabs>

The above snippet sends "Hello" in the thread with `parentMessageId` 100. Media and Custom messages can also be sent in threads using `setParentMessageId()`.

### Receiving Real-Time Messages

Use `MessageListener` to receive real-time thread messages. Check if the received message belongs to the active thread using `getParentMessageId()`.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const listenerID: string = "UNIQUE_LISTENER_ID";
    const activeThreadId: number = 100;

    CometChat.addMessageListener(
    listenerID,
    new CometChat.MessageListener({
    onTextMessageReceived: (textMessage: CometChat.TextMessage) => {
    if (textMessage.getParentMessageId() == activeThreadId) {
    console.log("Text message received for active thread.", textMessage);
    }
    },
    onMediaMessageReceived: (mediaMessage: CometChat.MediaMessage) => {
    if (mediaMessage.getParentMessageId() == activeThreadId) {
    console.log("Media message received for active thread.", mediaMessage);
    }
    },
    onCustomMessageReceived: (customMessage: CometChat.CustomMessage) => {
    if (customMessage.getParentMessageId() == activeThreadId) {
    console.log("Custom message received for active thread.", customMessage);
    }
    }
    })
    );

    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const listenerID = "UNIQUE_LISTENER_ID";
    const activeThreadId = 100;

    CometChat.addMessageListener(
    listenerID,
    new CometChat.MessageListener({
      onTextMessageReceived: textMessage => {
          if(textMessage.getParentMessageId() == activeThreadId) {
              console.log("Text message received for active thread.", textMessage);
          }
      },
      onMediaMessageReceived: mediaMessage => {
          if(mediaMessage.getParentMessageId() == activeThreadId) {
              console.log("Media message received for active thread.", mediaMessage);
          }
      },
      onCustomMessageReceived: customMessage => {
          if(customMessage.getParentMessageId() == activeThreadId) {
              console.log("Custom message received for active thread.", customMessage);
          }
      }
    })
    );
    ```
  </Tab>
</Tabs>

### Fetch all the messages for any particular thread.

Use `MessagesRequestBuilder` with `setParentMessageId()` to fetch messages belonging to a specific thread. Call `fetchPrevious()` to get messages (max 100 per request).

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    let limit: number = 30,
      parentMessageId: number = 1,
      messagesRequest: CometChat.MessagesRequest = new CometChat.MessagesRequestBuilder()
          .setLimit(limit)
          .setParentMessageId(parentMessageId)
          .build();

    messagesRequest.fetchPrevious().then(
    (messages: CometChat.BaseMessage[]) => {
    console.log("Messages for thread fetched successfully", messages);
    }, (error: CometChat.CometChatException) => {
    console.log("Message fetching failed with error:", error);
    }
    );

    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    let limit = 30;
    let parentMessageId = 1;
    let messagesRequest = new CometChat.MessagesRequestBuilder()
                          .setLimit(limit)
                          .setParentMessageId(parentMessageId)
                          .build();

    messagesRequest.fetchPrevious().then(
      messages => {
          console.log("Messages for thread fetched successfully", messages);
      }, error => {
          console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>
</Tabs>

The `fetchPrevious()` method returns an array of [`BaseMessage`](/sdk/reference/messages#basemessage) objects representing thread replies.

## Avoid Threaded Messages in User/Group Conversations

Use `hideReplies(true)` to exclude threaded messages when fetching messages for a conversation.

<Tabs>
  <Tab title="TypeScript (User)">
    ```typescript theme={null}
    let UID: string = "UID",
      limit: number = 30,
      messagesRequest: CometChat.MessagesRequest = new CometChat.MessagesRequestBuilder()
          .setUID(UID)
          .setLimit(limit)
          .hideReplies(true)
          .build();

    messagesRequest.fetchPrevious().then(
    (messages: CometChat.BaseMessage[]) => {
    console.log("Messages fetched successfully", messages);
    }, (error: CometChat.CometChatException) => {
    console.log("Message fetching failed with error:", error);
    }
    );

    ```
  </Tab>

  <Tab title="JavaScript (User)">
    ```javascript theme={null}
    let UID = "UID";
    let limit = 30;
    let messagesRequest = new CometChat.MessagesRequestBuilder()
                          .setUID(UID)
                          .setLimit(limit)
                          .hideReplies(true)
                          .build();

    messagesRequest.fetchPrevious().then(
      messages => {
          console.log("Messages fetched successfully", messages);
      }, error => {
          console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>

  <Tab title="TypeScript (Group)">
    ```typescript theme={null}
    let GUID: string = "GUID",
      limit: number = 30,
      messagesRequest: CometChat.MessagesRequest = new CometChat.MessagesRequestBuilder()
          .setGUID(GUID)
          .setLimit(limit)
          .hideReplies(true)
          .build();

    messagesRequest.fetchPrevious().then(
    (messages: CometChat.BaseMessage[]) => {
    console.log("Messages fetched successfully", messages);
    }, (error: CometChat.CometChatException) => {
    console.log("Message fetching failed with error:", error);
    }
    );

    ```
  </Tab>

  <Tab title="JavaScript (Group)">
    ```javascript theme={null}
    let GUID = "GUID";
    let limit = 30;
    let messagesRequest = new CometChat.MessagesRequestBuilder()
                          .setGUID(GUID)
                          .setLimit(limit)
                          .hideReplies(true)
                          .build();

    messagesRequest.fetchPrevious().then(
      messages => {
          console.log("Messages fetched successfully", messages);
      }, error => {
          console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>
</Tabs>

The response is an array of [`BaseMessage`](/sdk/reference/messages#basemessage) objects, excluding any messages that are replies within a thread. Only top-level messages in the conversation are returned.

<Warning>
  Always remove message listeners when they're no longer needed (e.g., on component unmount or page navigation). Failing to remove listeners can cause memory leaks and duplicate event handling.

  ```javascript theme={null}
  CometChat.removeMessageListener("UNIQUE_LISTENER_ID");
  ```
</Warning>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Send Messages" icon="paper-plane" href="/sdk/javascript/send-message">
    Send text, media, and custom messages to users and groups
  </Card>

  <Card title="Receive Messages" icon="inbox" href="/sdk/javascript/receive-message">
    Listen for incoming messages in real-time and fetch missed messages
  </Card>

  <Card title="Reactions" icon="face-smile" href="/sdk/javascript/reactions">
    Add emoji reactions to messages
  </Card>

  <Card title="Message Filtering" icon="filter" href="/sdk/javascript/message-filtering">
    Advanced message filtering with RequestBuilder
  </Card>
</CardGroup>
