Skip to main content
FieldValue
Package@cometchat/chat-uikit-react
FrameworkReact.js
ComponentsCometChatConversations, CometChatMessageHeader, CometChatMessageList, CometChatMessageComposer
LayoutTwo-panel — conversation list (left) + message view (right)
PrerequisiteComplete React.js Integration Steps 1–5 first
PatternWhatsApp Web, Slack, Microsoft Teams
This guide builds a two-panel chat layout — conversation list on the left, messages on the right. Users tap a conversation to open it. This assumes you’ve already completed React.js Integration (project created, UI Kit installed, init + login working, CSS imported).
Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time.

What You’re Building

Three sections working together:
  1. Sidebar (conversation list) — shows all active conversations (users and groups)
  2. Message view — displays chat messages for the selected conversation in real time
  3. Message composer — text input with support for media, emojis, and reactions

Step 1 — Create the Sidebar Component

Create a CometChatSelector folder inside src/:
src
CometChatSelector
CometChatSelector.tsx
CometChatSelector.css
CometChatSelector.tsx
import { useEffect, useState } from "react";
import {
  Conversation,
  Group,
  User,
  CometChat,
} from "@cometchat/chat-sdk-javascript";
import {
  CometChatConversations,
  CometChatUIKitLoginListener,
} from "@cometchat/chat-uikit-react";
import "./CometChatSelector.css";

interface SelectorProps {
  onSelectorItemClicked?: (
    input: User | Group | Conversation,
    type: string
  ) => void;
}

export const CometChatSelector = (props: SelectorProps) => {
  const { onSelectorItemClicked = () => {} } = props;
  const [loggedInUser, setLoggedInUser] = useState<CometChat.User | null>();
  const [activeItem, setActiveItem] = useState<
    CometChat.Conversation | CometChat.User | CometChat.Group | undefined
  >();

  useEffect(() => {
    const user = CometChatUIKitLoginListener.getLoggedInUser();
    setLoggedInUser(user);
  }, []);

  return (
    <>
      {loggedInUser && (
        <CometChatConversations
          activeConversation={
            activeItem instanceof CometChat.Conversation
              ? activeItem
              : undefined
          }
          onItemClick={(e) => {
            setActiveItem(e);
            onSelectorItemClicked(e, "updateSelectedItem");
          }}
        />
      )}
    </>
  );
};
Key points about the sidebar:
  • CometChatUIKitLoginListener.getLoggedInUser() checks for an active session — the component only renders if a user is logged in.
  • activeConversation highlights the currently selected conversation in the list.
  • onItemClick fires when a user taps a conversation, passing the Conversation object to the parent.

Step 2 — Update App.tsx and App.css

Wire the sidebar and message components together in your main app file.
App.tsx
import { useState } from "react";
import {
  CometChatMessageComposer,
  CometChatMessageHeader,
  CometChatMessageList,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatSelector } from "./CometChatSelector/CometChatSelector";
import "./App.css";
import "@cometchat/chat-uikit-react/css-variables.css";

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

  return (
    <div className="conversations-with-messages">
      {/* Sidebar — conversation list */}
      <div className="conversations-wrapper">
        <CometChatSelector
          onSelectorItemClicked={(activeItem) => {
            let item = activeItem;

            // Extract user/group from Conversation object
            if (activeItem instanceof CometChat.Conversation) {
              item = activeItem.getConversationWith();
            }

            if (item instanceof CometChat.User) {
              setSelectedUser(item as CometChat.User);
              setSelectedGroup(undefined);
            } else if (item instanceof CometChat.Group) {
              setSelectedUser(undefined);
              setSelectedGroup(item as CometChat.Group);
            } else {
              setSelectedUser(undefined);
              setSelectedGroup(undefined);
            }
          }}
        />
      </div>

      {/* Message view — header + messages + composer */}
      {selectedUser || selectedGroup ? (
        <div className="messages-wrapper">
          <CometChatMessageHeader user={selectedUser} group={selectedGroup} />
          <CometChatMessageList user={selectedUser} group={selectedGroup} />
          <CometChatMessageComposer
            user={selectedUser}
            group={selectedGroup}
          />
        </div>
      ) : (
        <div className="empty-conversation">
          Select a conversation to start chatting
        </div>
      )}
    </div>
  );
}

export default App;
How it works:
  • When a conversation is tapped, onSelectorItemClicked extracts the User or Group from the Conversation object.
  • selectedUser / selectedGroup state drives which chat is displayed — pass either user or group to the message components, never both.
  • The empty state shows until a conversation is selected.

Step 3 — Run the Project

npm run dev
You should see the conversation list on the left. Tap any conversation to load messages on the right.

Next Steps