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

Theming

Customize colors, fonts, and styles to match your brand

Components Overview

Browse all prebuilt UI components

React.js Integration

Back to the main setup guide

Core Features

Chat features included out of the box