Skip to main content
{
  "component": "CometChatConversations",
  "package": "@cometchat/chat-uikit-react",
  "import": "import { CometChatConversations } from \"@cometchat/chat-uikit-react\";",
  "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";",
  "description": "Scrollable list of recent one-on-one and group conversations for the logged-in user.",
  "cssRootClass": ".cometchat-conversations",
  "primaryOutput": {
    "prop": "onItemClick",
    "type": "(conversation: CometChat.Conversation) => void"
  },
  "props": {
    "data": {
      "conversationsRequestBuilder": {
        "type": "CometChat.ConversationsRequestBuilder",
        "default": "SDK default (30 per page)",
        "note": "Pass the builder, not the result of .build()"
      },
      "activeConversation": {
        "type": "CometChat.Conversation",
        "default": "undefined"
      },
      "lastMessageDateTimeFormat": {
        "type": "CalendarObject",
        "default": "Component default (hh:mm A today, [yesterday], DD/MM/YYYY other days)",
        "note": "Falls back to global CometChatLocalize.calendarObject if not set"
      }
    },
    "callbacks": {
      "onItemClick": "(conversation: CometChat.Conversation) => void",
      "onSelect": "(conversation: CometChat.Conversation, selected: boolean) => void",
      "onError": "((error: CometChat.CometChatException) => void) | null",
      "onSearchBarClicked": "() => void"
    },
    "visibility": {
      "hideReceipts": { "type": "boolean", "default": false },
      "hideError": { "type": "boolean", "default": false },
      "hideDeleteConversation": { "type": "boolean", "default": false },
      "hideUserStatus": { "type": "boolean", "default": false },
      "hideGroupType": { "type": "boolean", "default": false },
      "showSearchBar": { "type": "boolean", "default": false },
      "showScrollbar": { "type": "boolean", "default": false }
    },
    "sound": {
      "disableSoundForMessages": { "type": "boolean", "default": false },
      "customSoundForMessages": { "type": "string", "default": "built-in" }
    },
    "selection": {
      "selectionMode": {
        "type": "SelectionMode",
        "values": ["SelectionMode.single (0)", "SelectionMode.multiple (1)", "SelectionMode.none (2)"],
        "default": "SelectionMode.none"
      }
    },
    "viewSlots": {
      "itemView": "(conversation: CometChat.Conversation) => JSX.Element",
      "leadingView": "(conversation: CometChat.Conversation) => JSX.Element",
      "titleView": "(conversation: CometChat.Conversation) => JSX.Element",
      "subtitleView": "(conversation: CometChat.Conversation) => JSX.Element",
      "trailingView": "(conversation: CometChat.Conversation) => JSX.Element",
      "headerView": "JSX.Element",
      "searchView": "JSX.Element",
      "loadingView": "JSX.Element",
      "emptyView": "JSX.Element",
      "errorView": "JSX.Element",
      "options": "((conversation: CometChat.Conversation) => CometChatOption[]) | null"
    },
    "formatting": {
      "textFormatters": {
        "type": "CometChatTextFormatter[]",
        "default": "default formatters from data source"
      }
    }
  },
  "events": [
    {
      "name": "CometChatConversationEvents.ccConversationDeleted",
      "payload": "CometChat.Conversation",
      "description": "Conversation deleted from list"
    },
    {
      "name": "CometChatConversationEvents.ccUpdateConversation",
      "payload": "CometChat.Conversation",
      "description": "Conversation updated"
    },
    {
      "name": "CometChatConversationEvents.ccMarkConversationAsRead",
      "payload": "CometChat.Conversation",
      "description": "Conversation marked as read"
    }
  ],
  "sdkListeners": [
    "onTextMessageReceived",
    "onMediaMessageReceived",
    "onCustomMessageReceived",
    "onTypingStarted",
    "onTypingEnded",
    "onMessagesDelivered",
    "onMessagesRead",
    "onMessagesDeliveredToAll",
    "onMessagesReadByAll",
    "onUserOnline",
    "onUserOffline",
    "onGroupMemberJoined",
    "onGroupMemberLeft",
    "onGroupMemberKicked",
    "onGroupMemberBanned",
    "onMemberAddedToGroup"
  ],
  "compositionExample": {
    "description": "Sidebar conversations wired to message view",
    "components": [
      "CometChatConversations",
      "CometChatMessageHeader",
      "CometChatMessageList",
      "CometChatMessageComposer"
    ],
    "flow": "onItemClick emits CometChat.Conversation -> extract User/Group via getConversationWith() -> pass to MessageHeader, MessageList, MessageComposer"
  },
  "types": {
    "CalendarObject": {
      "today": "string | undefined",
      "yesterday": "string | undefined",
      "lastWeek": "string | undefined",
      "otherDays": "string | undefined",
      "relativeTime": {
        "minute": "string | undefined",
        "minutes": "string | undefined",
        "hour": "string | undefined",
        "hours": "string | undefined"
      }
    },
    "CometChatOption": {
      "id": "string | undefined",
      "title": "string | undefined",
      "iconURL": "string | undefined",
      "onClick": "(() => void) | undefined"
    },
    "SelectionMode": {
      "single": 0,
      "multiple": 1,
      "none": 2
    }
  }
}

Where It Fits

CometChatConversations is a sidebar list component. It renders recent conversations and emits the selected CometChat.Conversation via onItemClick. Wire it to CometChatMessageHeader, CometChatMessageList, and CometChatMessageComposer to build a standard two-panel chat layout.
import { useState } from "react";
import {
  CometChatConversations,
  CometChatMessageHeader,
  CometChatMessageList,
  CometChatMessageComposer,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import "@cometchat/chat-uikit-react/css-variables.css";

function ChatApp() {
  const [selectedUser, setSelectedUser] = useState<CometChat.User>();
  const [selectedGroup, setSelectedGroup] = useState<CometChat.Group>();

  const handleItemClick = (conversation: CometChat.Conversation) => {
    const entity = conversation.getConversationWith();
    if (entity instanceof CometChat.User) {
      setSelectedUser(entity);
      setSelectedGroup(undefined);
    } else if (entity instanceof CometChat.Group) {
      setSelectedGroup(entity);
      setSelectedUser(undefined);
    }
  };

  return (
    <div style={{ display: "flex", height: "100vh", width: "100vw" }}>
      <div style={{ width: 480, height: "100%" }}>
        <CometChatConversations onItemClick={handleItemClick} />
      </div>
      {selectedUser || selectedGroup ? (
        <div style={{ flex: 1, display: "flex", flexDirection: "column" }}>
          <CometChatMessageHeader user={selectedUser} group={selectedGroup} />
          <CometChatMessageList user={selectedUser} group={selectedGroup} />
          <CometChatMessageComposer user={selectedUser} group={selectedGroup} />
        </div>
      ) : (
        <div style={{ flex: 1, display: "grid", placeItems: "center", background: "#F5F5F5", color: "#727272" }}>
          Select a conversation
        </div>
      )}
    </div>
  );
}
Open in CodeSandbox

Minimal Render

import { CometChatConversations } from "@cometchat/chat-uikit-react";
import "@cometchat/chat-uikit-react/css-variables.css";

function ConversationsDemo() {
  return (
    <div style={{ width: "100%", height: "100%" }}>
      <CometChatConversations />
    </div>
  );
}

export default ConversationsDemo;
Root CSS class: .cometchat-conversations

Filtering Conversations

Pass a CometChat.ConversationsRequestBuilder to conversationsRequestBuilder. Pass the builder instance — not the result of .build().
import { CometChatConversations } from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";

function FilteredConversations() {
  return (
    <CometChatConversations
      conversationsRequestBuilder={
        new CometChat.ConversationsRequestBuilder()
          .setConversationType("user")
          .setLimit(10)
      }
    />
  );
}

Filter Recipes

RecipeCode
Only user conversationsnew CometChat.ConversationsRequestBuilder().setConversationType("user")
Only group conversationsnew CometChat.ConversationsRequestBuilder().setConversationType("group")
Limit to 10 per pagenew CometChat.ConversationsRequestBuilder().setLimit(10)
With specific tagsnew CometChat.ConversationsRequestBuilder().setTags(["vip"])
Filter by user tagsnew CometChat.ConversationsRequestBuilder().withUserAndGroupTags(true).setUserTags(["premium"])
Filter by group tagsnew CometChat.ConversationsRequestBuilder().withUserAndGroupTags(true).setGroupTags(["support"])
Default page size is 30. The component uses infinite scroll — the next page loads as the user scrolls to the bottom. Refer to ConversationRequestBuilder for the full builder API.

Actions and Events

Callback Props

onItemClick

Fires when a conversation row is tapped. Primary navigation hook — set the active conversation and render the message view.
import { CometChatConversations } from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";

function ConversationsWithClick() {
  const handleItemClick = (conversation: CometChat.Conversation) => {
    console.log("Selected:", conversation.getConversationId());
  };

  return <CometChatConversations onItemClick={handleItemClick} />;
}

onSelect

Fires when a conversation is checked/unchecked in multi-select mode. Requires selectionMode to be set.
import { useState } from "react";
import {
  CometChatConversations,
  SelectionMode,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";

function BatchSelectDemo() {
  const [selected, setSelected] = useState<Set<string>>(new Set());

  const handleSelect = (conversation: CometChat.Conversation, isSelected: boolean) => {
    setSelected((prev) => {
      const next = new Set(prev);
      const id = conversation.getConversationId();
      isSelected ? next.add(id) : next.delete(id);
      return next;
    });
  };

  return (
    <CometChatConversations
      selectionMode={SelectionMode.multiple}
      onSelect={handleSelect}
    />
  );
}

onError

Fires on internal errors (network failure, auth issue, SDK exception).
import { CometChatConversations } from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";

function ConversationsWithErrorHandler() {
  return (
    <CometChatConversations
      onError={(error: CometChat.CometChatException) => {
        console.error("CometChatConversations error:", error);
      }}
    />
  );
}

onSearchBarClicked

Fires when the search bar is clicked. Requires showSearchBar={true}.
import { CometChatConversations } from "@cometchat/chat-uikit-react";

function ConversationsWithSearch() {
  return (
    <CometChatConversations
      showSearchBar={true}
      onSearchBarClicked={() => {
        console.log("Search bar clicked");
      }}
    />
  );
}

Global UI Events

CometChatConversationEvents emits events subscribable from anywhere in the application. Subscribe in a useEffect and unsubscribe on cleanup.
EventFires whenPayload
ccConversationDeletedA conversation is deleted from the listCometChat.Conversation
ccUpdateConversationA conversation is updated (last message change, metadata update)CometChat.Conversation
ccMarkConversationAsReadA conversation is marked as readCometChat.Conversation
When to use: sync external UI with conversation state changes. For example, update an unread count badge in a tab bar when ccMarkConversationAsRead fires, or remove a conversation from a custom sidebar when ccConversationDeleted fires.
import { useEffect } from "react";
import { CometChatConversationEvents } from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";

function useConversationEvents() {
  useEffect(() => {
    const deletedSub = CometChatConversationEvents.ccConversationDeleted.subscribe(
      (conversation: CometChat.Conversation) => {
        console.log("Deleted:", conversation.getConversationId());
      }
    );
    const updatedSub = CometChatConversationEvents.ccUpdateConversation.subscribe(
      (conversation: CometChat.Conversation) => {
        console.log("Updated:", conversation.getConversationId());
      }
    );
    const readSub = CometChatConversationEvents.ccMarkConversationAsRead.subscribe(
      (conversation: CometChat.Conversation) => {
        console.log("Marked as read:", conversation.getConversationId());
      }
    );

    return () => {
      deletedSub?.unsubscribe();
      updatedSub?.unsubscribe();
      readSub?.unsubscribe();
    };
  }, []);
}

SDK Events (Real-Time, Automatic)

The component listens to these SDK events internally. No manual attachment needed unless additional side effects are required.
SDK ListenerInternal behavior
onTextMessageReceived / onMediaMessageReceived / onCustomMessageReceivedMoves conversation to top, updates last message preview and unread count
onTypingStarted / onTypingEndedShows/hides typing indicator in the subtitle
onMessagesDelivered / onMessagesRead / onMessagesDeliveredToAll / onMessagesReadByAllUpdates receipt ticks (unless hideReceipts={true})
onUserOnline / onUserOfflineUpdates online/offline status dot (unless hideUserStatus={true})
onGroupMemberJoined / onGroupMemberLeft / onGroupMemberKicked / onGroupMemberBanned / onMemberAddedToGroupUpdates group conversation metadata
Automatic: new messages, typing indicators, receipts, user presence, group membership changes. Manual: deleting a conversation via the SDK directly (not through the component’s context menu) requires emitting CometChatConversationEvents.ccConversationDeleted for the UI to update.
In React 18 StrictMode, useEffect runs twice on mount in development. The component handles listener cleanup internally, but any additional listeners added alongside the component need cleanup in the useEffect return function to avoid duplicate event handling.

Custom View Slots

Each slot replaces a section of the default UI. Slots that accept a conversation parameter receive the CometChat.Conversation object for that row.
SlotSignatureReplaces
itemView(conversation: CometChat.Conversation) => JSX.ElementEntire list item row
leadingView(conversation: CometChat.Conversation) => JSX.ElementAvatar / left section
titleView(conversation: CometChat.Conversation) => JSX.ElementName / title text
subtitleView(conversation: CometChat.Conversation) => JSX.ElementLast message preview
trailingView(conversation: CometChat.Conversation) => JSX.ElementTimestamp / badge / right section
headerViewJSX.ElementEntire header bar
searchViewJSX.ElementSearch bar
loadingViewJSX.ElementLoading spinner
emptyViewJSX.ElementEmpty state
errorViewJSX.ElementError state
options(conversation: CometChat.Conversation) => CometChatOption[]Context menu / hover actions

itemView

Replace the entire list item row. Default:
Customized:
import { CometChat } from "@cometchat/chat-sdk-javascript";
import {
  CometChatListItem,
  CometChatConversations,
  CometChatDate,
} from "@cometchat/chat-uikit-react";

function CustomItemViewConversations() {
  const getItemView = (conversation: CometChat.Conversation) => {
    const title = conversation.getConversationWith().getName();
    const timestamp = conversation?.getLastMessage()?.getSentAt();

    return (
      <CometChatListItem
        title={title}
        avatarName={title}
        id={conversation.getConversationId()}
        trailingView={<CometChatDate timestamp={timestamp} />}
        onListItemClicked={() => {
          // handle click
        }}
      />
    );
  };

  return <CometChatConversations itemView={getItemView} />;
}

leadingView

Replace the avatar / left section. Typing-aware avatar example.
import { useEffect, useRef, useState } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import {
  CometChatConversations,
  CometChatAvatar,
  CometChatUIKitLoginListener,
} from "@cometchat/chat-uikit-react";

function TypingAwareConversations() {
  const [isTyping, setIsTyping] = useState(false);
  const typingObjRef = useRef<CometChat.TypingIndicator | null>(null);
  const loggedInUser = CometChatUIKitLoginListener.getLoggedInUser();

  useEffect(() => {
    const listenerId = "typing_demo_" + Date.now();
    CometChat.addMessageListener(
      listenerId,
      new CometChat.MessageListener({
        onTypingStarted: (typingIndicator: CometChat.TypingIndicator) => {
          typingObjRef.current = typingIndicator;
          setIsTyping(true);
        },
        onTypingEnded: (typingIndicator: CometChat.TypingIndicator) => {
          if (
            typingObjRef.current &&
            typingObjRef.current.getSender().getUid() ===
              typingIndicator.getSender().getUid()
          ) {
            typingObjRef.current = null;
            setIsTyping(false);
          }
        },
      })
    );
    return () => {
      CometChat.removeMessageListener(listenerId);
    };
  }, []);

  const getLeadingView = (conversation: CometChat.Conversation) => {
    const entity = conversation.getConversationWith();
    const isUser = entity instanceof CometChat.User;
    const isGroup = entity instanceof CometChat.Group;

    const isMyTyping = isUser
      ? (entity as CometChat.User).getUid() ===
          typingObjRef.current?.getSender().getUid() &&
        loggedInUser?.getUid() === typingObjRef.current?.getReceiverId()
      : isGroup &&
        (entity as CometChat.Group).getGuid() ===
          typingObjRef.current?.getReceiverId();

    const avatar = isUser
      ? (entity as CometChat.User).getAvatar()
      : (entity as CometChat.Group).getIcon();

    return (
      <div className="conversations__leading-view">
        <CometChatAvatar
          image={isTyping && isMyTyping ? undefined : avatar}
          name={isTyping && isMyTyping ? undefined : entity.getName()}
        />
      </div>
    );
  };

  return <CometChatConversations leadingView={getLeadingView} />;
}

trailingView

Replace the timestamp / badge / right section. Relative time badge example.
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatConversations } from "@cometchat/chat-uikit-react";

function RelativeTimeConversations() {
  const getTrailingView = (conv: CometChat.Conversation) => {
    if (!conv.getLastMessage()) return <></>;

    const timestamp = conv.getLastMessage()?.getSentAt() * 1000;
    const now = Date.now();
    const diffInMinutes = Math.floor((now - timestamp) / (1000 * 60));
    const diffInHours = Math.floor((now - timestamp) / (1000 * 60 * 60));

    let className = "conversations__trailing-view-min";
    let topLabel = `${diffInMinutes}`;
    let bottomLabel = diffInMinutes === 1 ? "Min ago" : "Mins ago";

    if (diffInHours >= 1 && diffInHours <= 10) {
      className = "conversations__trailing-view-hour";
      topLabel = `${diffInHours}`;
      bottomLabel = diffInHours === 1 ? "Hour ago" : "Hours ago";
    } else if (diffInHours > 10) {
      className = "conversations__trailing-view-date";
      const time = new Date(timestamp);
      topLabel = time.toLocaleDateString("en-US", { day: "numeric" });
      bottomLabel = time.toLocaleDateString("en-US", { month: "short", year: "numeric" });
    }

    return (
      <div className={`conversations__trailing-view ${className}`}>
        <span className="conversations__trailing-view-time">{topLabel}</span>
        <span className="conversations__trailing-view-status">{bottomLabel}</span>
      </div>
    );
  };

  return <CometChatConversations trailingView={getTrailingView} />;
}

titleView

Replace the name / title text. Inline user status example.
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatConversations } from "@cometchat/chat-uikit-react";

function StatusTitleConversations() {
  const getTitleView = (conversation: CometChat.Conversation) => {
    const user =
      conversation.getConversationType() === "user"
        ? (conversation.getConversationWith() as CometChat.User)
        : undefined;

    return (
      <div className="conversations__title-view">
        <span className="conversations__title-view-name">
          {user
            ? conversation.getConversationWith().getName() + " · "
            : conversation.getConversationWith().getName()}
        </span>
        {user && (
          <span className="conversations__title-view-status">
            {user.getStatusMessage()}
          </span>
        )}
      </div>
    );
  };

  return <CometChatConversations titleView={getTitleView} />;
}

subtitleView

Replace the last message preview text. Default:
Customized:
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatConversations } from "@cometchat/chat-uikit-react";

function formatTimestamp(timestamp: number): string {
  return new Date(timestamp * 1000).toLocaleString();
}

function SubtitleConversations() {
  const getSubtitleView = (conversation: CometChat.Conversation) => {
    if (conversation.getConversationType() === "user") {
      return (
        <>
          Last active:{" "}
          {formatTimestamp(
            (conversation.getConversationWith() as CometChat.User).getLastActiveAt()
          )}
        </>
      );
    }
    return (
      <>
        Created:{" "}
        {formatTimestamp(
          (conversation.getConversationWith() as CometChat.Group).getCreatedAt()
        )}
      </>
    );
  };

  return <CometChatConversations subtitleView={getSubtitleView} />;
}

headerView

Replace the entire header bar.
import {
  CometChatButton,
  CometChatConversations,
  getLocalizedString,
} from "@cometchat/chat-uikit-react";

function CustomHeaderConversations() {
  return (
    <CometChatConversations
      headerView={
        <div className="conversations__header">
          <div className="conversations__header__title">
            {getLocalizedString("CHATS")}
          </div>
          <CometChatButton onClick={() => { /* handle click */ }} />
        </div>
      }
    />
  );
}

options

Replace the context menu / hover actions on each conversation item. Default:
Customized:
import { CometChat } from "@cometchat/chat-sdk-javascript";
import {
  CometChatOption,
  CometChatConversations,
} from "@cometchat/chat-uikit-react";

function CustomOptionsConversations() {
  const getOptions = (conversation: CometChat.Conversation) => [
    new CometChatOption({
      title: "Delete",
      id: "delete",
      onClick: () => { /* delete logic */ },
    }),
    new CometChatOption({
      title: "Mute Notification",
      id: "mute",
      onClick: () => { /* mute logic */ },
    }),
    new CometChatOption({
      title: "Mark as Unread",
      id: "unread",
      onClick: () => { /* mark unread logic */ },
    }),
    new CometChatOption({
      title: "Block",
      id: "block",
      onClick: () => { /* block logic */ },
    }),
  ];

  return <CometChatConversations options={getOptions} />;
}
// CometChatOption interface
interface CometChatOption {
  id?: string;       // Unique identifier
  title?: string;    // Display text
  iconURL?: string;  // Icon asset URL
  onClick?: () => void; // Click handler
}

textFormatters

Custom text formatters for the conversation subtitle. Array of CometChatTextFormatter instances. If not provided, default formatters from the data source are used.
import { CometChatConversations } from "@cometchat/chat-uikit-react";
import ShortcutFormatter from "./ShortCutFormatter";

function FormattedConversations() {
  return (
    <CometChatConversations textFormatters={[new ShortcutFormatter()]} />
  );
}
See CometChatMentionsFormatter for mention formatting.

lastMessageDateTimeFormat

Customize the last message timestamp format using a CalendarObject.
// CalendarObject interface (from source)
class CalendarObject {
  today?: string;
  yesterday?: string;
  lastWeek?: string;
  otherDays?: string;
  relativeTime?: {
    minute?: string;
    minutes?: string;
    hour?: string;
    hours?: string;
  };
}
import {
  CometChatConversations,
  CalendarObject,
} from "@cometchat/chat-uikit-react";

function CustomDateConversations() {
  const dateFormat = new CalendarObject({
    today: "DD MMM, hh:mm A",
    yesterday: "DD MMM, hh:mm A",
    otherDays: "DD MMM, hh:mm A",
  });

  return <CometChatConversations lastMessageDateTimeFormat={dateFormat} />;
}
If no property is passed in the CalendarObject, the component checks the global configuration first. If also missing there, the component’s default formatting applies.

Common Patterns

Custom empty state with CTA

import { CometChatConversations } from "@cometchat/chat-uikit-react";

function EmptyStateConversations() {
  return (
    <CometChatConversations
      emptyView={
        <div style={{ textAlign: "center", padding: 40 }}>
          <p>No conversations yet</p>
          <button onClick={() => { /* navigate to contacts */ }}>
            Start a conversation
          </button>
        </div>
      }
    />
  );
}

Hide all chrome — minimal list

import { CometChatConversations } from "@cometchat/chat-uikit-react";

function MinimalConversations() {
  return (
    <CometChatConversations
      hideReceipts={true}
      hideUserStatus={true}
      hideGroupType={true}
      hideDeleteConversation={true}
    />
  );
}
import { CometChatConversations } from "@cometchat/chat-uikit-react";

function SearchableConversations() {
  return (
    <CometChatConversations
      showSearchBar={true}
      showScrollbar={true}
    />
  );
}

CSS Architecture

The component uses CSS custom properties (design tokens) defined in @cometchat/chat-uikit-react/css-variables.css. The cascade:
  1. Global tokens (e.g., --cometchat-primary-color, --cometchat-background-color-01) are set on the .cometchat root wrapper.
  2. Component CSS (.cometchat-conversations) consumes these tokens via var() with fallback values.
  3. Overrides target .cometchat-conversations descendant selectors in a global stylesheet.
To scope overrides to a single instance when multiple CometChatConversations exist on the same page, wrap the component in a container and scope selectors:
.sidebar-left .cometchat-conversations .cometchat-badge {
  background: #e5484d;
}
Overrides survive component updates because the component never sets inline styles on these elements — all styling flows through CSS classes and custom properties.

Key Selectors

TargetSelector
Root.cometchat-conversations
Header title.cometchat-conversations .cometchat-list__header-title
List item.cometchat-conversations .cometchat-list-item
Body title.cometchat-conversations .cometchat-list-item__body-title
Avatar.cometchat-conversations .cometchat-avatar
Avatar text.cometchat-conversations .cometchat-avatar__text
Unread badge.cometchat-conversations .cometchat-badge
Subtitle text.cometchat-conversations .cometchat-conversations__subtitle-text
Status indicator.cometchat-conversations .cometchat-status-indicator
Read receipts.cometchat-conversations .cometchat-receipts-read
Active item.cometchat-conversations__list-item-active .cometchat-list-item
Typing indicator.cometchat-conversations__subtitle-typing
Trailing view.cometchat-conversations__trailing-view

Example: Brand-themed conversations

.cometchat-conversations .cometchat-list-item__body-title,
.cometchat-conversations .cometchat-list__header-title,
.cometchat-conversations .cometchat-avatar__text,
.cometchat-conversations .cometchat-badge,
.cometchat-conversations .cometchat-conversations__subtitle-text {
  font-family: "SF Pro";
}

.cometchat-conversations .cometchat-list__header-title {
  background: #fef8f8;
  border-bottom: 2px solid #f4b6b8;
}

.cometchat-conversations .cometchat-avatar {
  background: #f0999b;
}

.cometchat-conversations .cometchat-status-indicator {
  min-width: 10px;
  height: 10px;
}

.cometchat-conversations .cometchat-badge {
  background: #e5484d;
}

.cometchat-conversations .cometchat-receipts-read {
  background: #e96b6f;
}

Customization Matrix

What to changeWhereProperty/APIExample
Override behavior on user interactionComponent propson<Event> callbacksonItemClick={(c) => setActive(c)}
Filter which conversations appearComponent propsconversationsRequestBuilderconversationsRequestBuilder={new CometChat.ConversationsRequestBuilder().setLimit(10)}
Toggle visibility of UI elementsComponent propshide<Feature> boolean propshideReceipts={true}
Replace a section of the list itemComponent props<slot>View render propsitemView={(conversation) => <div>...</div>}
Change colors, fonts, spacingGlobal CSSTarget .cometchat-conversations class.cometchat-conversations .cometchat-badge { background: #e5484d; }

Accessibility

The component renders a scrollable list of interactive items. Each conversation row is keyboard-focusable and activates on Enter/Space. The context menu (options) is accessible via keyboard. The unread badge count is exposed as text content. Avatar images include the conversation name as alt text. For screen readers, the conversation list is rendered as a semantic list. Status indicators (online/offline, group type icons) use CSS mask images — add aria-label attributes via itemView if screen reader descriptions are needed for these visual indicators.

Props

All props are optional. Sorted alphabetically.

activeConversation

Highlights the specified conversation in the list.
TypeCometChat.Conversation
Defaultundefined
Must be a reference-equal object from the SDK; a manually constructed object will not match.

conversationsRequestBuilder

Controls which conversations load and in what order.
TypeCometChat.ConversationsRequestBuilder
DefaultSDK default (30 per page)
Pass the builder instance, not the result of .build().

customSoundForMessages

URL to a custom audio file for incoming message notifications.
Typestring
DefaultBuilt-in sound
Must be a valid audio URL accessible from the browser.

disableSoundForMessages

Disables the notification sound for incoming messages.
Typeboolean
Defaultfalse

emptyView

Custom component displayed when there are no conversations.
TypeJSX.Element
DefaultBuilt-in empty state

errorView

Custom component displayed when an error occurs.
TypeJSX.Element
DefaultBuilt-in error state
Hidden when hideError={true}.

headerView

Custom component rendered as the entire header bar.
TypeJSX.Element
DefaultBuilt-in header with title

hideDeleteConversation

Hides the delete option in the context menu.
Typeboolean
Defaultfalse

hideError

Hides the default and custom error views.
Typeboolean
Defaultfalse
Also suppresses errorView if set.

hideGroupType

Hides the group type icon (public/private/password).
Typeboolean
Defaultfalse

hideReceipts

Hides message read/delivery receipt indicators.
Typeboolean
Defaultfalse

hideUserStatus

Hides the online/offline status indicator.
Typeboolean
Defaultfalse

itemView

Custom renderer for the entire list item row.
Type(conversation: CometChat.Conversation) => JSX.Element
DefaultBuilt-in list item

lastMessageDateTimeFormat

Format for displaying the timestamp of the last message.
TypeCalendarObject
DefaultComponent default (hh:mm A today, [yesterday], DD/MM/YYYY other days)
class CalendarObject {
  today?: string;
  yesterday?: string;
  lastWeek?: string;
  otherDays?: string;
  relativeTime?: {
    minute?: string;
    minutes?: string;
    hour?: string;
    hours?: string;
  };
}
Falls back to global calendar configuration if not set.

leadingView

Custom renderer for the avatar / left section.
Type(conversation: CometChat.Conversation) => JSX.Element
DefaultBuilt-in avatar

loadingView

Custom component displayed during the loading state.
TypeJSX.Element
DefaultBuilt-in shimmer

onError

Callback fired when the component encounters an error.
Type((error: CometChat.CometChatException) => void) | null
Defaultundefined

onItemClick

Callback fired when a conversation row is clicked.
Type(conversation: CometChat.Conversation) => void
Defaultundefined

onSearchBarClicked

Callback fired when the search bar is clicked. Requires showSearchBar={true}.
Type() => void
Defaultundefined

onSelect

Callback fired when a conversation is selected/deselected. Requires selectionMode to be set.
Type(conversation: CometChat.Conversation, selected: boolean) => void
Defaultundefined

options

Custom context menu / hover actions for each conversation item.
Type((conversation: CometChat.Conversation) => CometChatOption[]) | null
DefaultBuilt-in delete option
class CometChatOption {
  id?: string;
  title?: string;
  iconURL?: string;
  onClick?: () => void;
}

searchView

Custom search bar component in the header.
TypeJSX.Element
DefaultBuilt-in search bar

selectionMode

Enables single or multi-select checkboxes on list items.
TypeSelectionMode
DefaultSelectionMode.none
enum SelectionMode {
  single,    // 0
  multiple,  // 1
  none,      // 2
}
Must pair with onSelect to capture selections.

showScrollbar

Shows the scrollbar in the conversation list.
Typeboolean
Defaultfalse

showSearchBar

Shows a search bar at the top of the list.
Typeboolean
Defaultfalse

subtitleView

Custom renderer for the last message preview text.
Type(conversation: CometChat.Conversation) => JSX.Element
DefaultBuilt-in subtitle

textFormatters

Custom text formatters for the conversation subtitle.
TypeCometChatTextFormatter[]
DefaultDefault formatters from data source
See CometChatMentionsFormatter for mention formatting.

titleView

Custom renderer for the name / title text.
Type(conversation: CometChat.Conversation) => JSX.Element
DefaultBuilt-in title

trailingView

Custom renderer for the timestamp / badge / right section.
Type(conversation: CometChat.Conversation) => JSX.Element
DefaultBuilt-in trailing view

Events

EventPayloadFires when
CometChatConversationEvents.ccConversationDeletedCometChat.ConversationConversation deleted from list
CometChatConversationEvents.ccUpdateConversationCometChat.ConversationConversation updated
CometChatConversationEvents.ccMarkConversationAsReadCometChat.ConversationConversation marked as read
All events are Subject<CometChat.Conversation> from RxJS. Subscribe with .subscribe(), unsubscribe with the returned subscription’s .unsubscribe().

CSS Selectors

TargetSelector
Root.cometchat-conversations
Header title.cometchat-conversations .cometchat-list__header-title
List item.cometchat-conversations .cometchat-list-item
Body title.cometchat-conversations .cometchat-list-item__body-title
Avatar.cometchat-conversations .cometchat-avatar
Avatar text.cometchat-conversations .cometchat-avatar__text
Unread badge.cometchat-conversations .cometchat-badge
Subtitle text.cometchat-conversations .cometchat-conversations__subtitle-text
Subtitle sender.cometchat-conversations__subtitle-text-sender
Status indicator (online).cometchat-conversations__list-item-online .cometchat-list-item__status
Group type (password).cometchat-conversations__list-item-password .cometchat-list-item__status
Group type (private).cometchat-conversations__list-item-private .cometchat-list-item__status
Read receipts.cometchat-conversations__subtitle-receipts-read
Delivered receipts.cometchat-conversations__subtitle-receipts-delivered
Sent receipts.cometchat-conversations__subtitle-receipts-sent
Error receipts.cometchat-conversations__subtitle-receipts-error
Active item.cometchat-conversations__list-item-active .cometchat-list-item
Typing indicator.cometchat-conversations__subtitle-typing
Trailing view.cometchat-conversations__trailing-view
Badge count.cometchat-conversations__trailing-view-badge-count
Empty state.cometchat-conversations__empty-state-view
Error state.cometchat-conversations__error-state-view
Shimmer loading.cometchat-conversations__shimmer
Context menu.cometchat-conversations__trailing-view-options
Mentions highlight.cometchat-conversations__subtitle-text .cometchat-mentions
@you mentions.cometchat-conversations__subtitle-text .cometchat-mentions-you