Documentation Index
Fetch the complete documentation index at: https://cometchat-22654f5b-react-uikit-v7.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Goal
By the end of this guide you will have a chat interface where users can initiate new one-on-one conversations by selecting from a user list, or start group chats by selecting from available groups — then immediately begin messaging.
Prerequisites
Components Used
| Component / API | Purpose |
|---|
CometChatUsers | Lists available users for 1:1 chat selection |
CometChatGroups | Lists available groups for group chat selection |
CometChatConversations | Shows existing conversations |
CometChatMessageHeader | Displays selected user/group info |
CometChatMessageList | Renders conversation messages |
CometChatMessageComposer | Text input for the conversation |
CometChat.joinGroup() | SDK method to join a group |
Step 1: Set up the app shell
Wrap your application in CometChatProvider and create a layout that will hold the conversation area and a trigger for starting new chats.
import { useState } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatProvider } from "@cometchat/chat-uikit-react";
import "@cometchat/chat-uikit-react/styles";
import { NewChatApp } from "./NewChatApp";
function App() {
return (
<CometChatProvider
appId="YOUR_APP_ID"
region="YOUR_REGION"
authKey="YOUR_AUTH_KEY"
>
<NewChatApp />
</CometChatProvider>
);
}
export default App;
Step 2: Add a “New Chat” trigger
Create a button that opens a selection panel. Use component state to toggle between the conversations view and the user/group selection view.
import { useState } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatConversations } from "@cometchat/chat-uikit-react";
type ChatTarget =
| { type: "user"; entity: CometChat.User }
| { type: "group"; entity: CometChat.Group };
function NewChatApp() {
const [showNewChat, setShowNewChat] = useState(false);
const [activeChat, setActiveChat] = useState<ChatTarget | null>(null);
return (
<div style={{ display: "flex", height: "100vh" }}>
<div style={{ width: "320px", borderRight: "1px solid #e0e0e0", display: "flex", flexDirection: "column" }}>
<div style={{ padding: "8px", borderBottom: "1px solid #e0e0e0" }}>
<button
onClick={() => setShowNewChat(!showNewChat)}
style={{ width: "100%", padding: "8px" }}
>
{showNewChat ? "Cancel" : "New Chat"}
</button>
</div>
{showNewChat ? (
<UserGroupSelector
onSelectUser={(user) => {
setActiveChat({ type: "user", entity: user });
setShowNewChat(false);
}}
onSelectGroup={(group) => {
setActiveChat({ type: "group", entity: group });
setShowNewChat(false);
}}
/>
) : (
<div style={{ flex: 1, overflow: "hidden" }}>
<CometChatConversations
onItemClick={(conversation) => {
const entity = conversation.getConversationWith();
if (entity instanceof CometChat.User) {
setActiveChat({ type: "user", entity });
} else if (entity instanceof CometChat.Group) {
setActiveChat({ type: "group", entity });
}
}}
/>
</div>
)}
</div>
<div style={{ flex: 1 }}>
{activeChat ? (
<ChatView target={activeChat} />
) : (
<div style={{ display: "flex", alignItems: "center", justifyContent: "center", height: "100%" }}>
<p>Select a conversation or start a new chat</p>
</div>
)}
</div>
</div>
);
}
Step 3: Build the user/group selector
Use CometChatUsers and CometChatGroups to let the user pick a chat target. Add tabs to switch between users and groups.
import { useState } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatUsers, CometChatGroups } from "@cometchat/chat-uikit-react";
function UserGroupSelector({
onSelectUser,
onSelectGroup,
}: {
onSelectUser: (user: CometChat.User) => void;
onSelectGroup: (group: CometChat.Group) => void;
}) {
const [tab, setTab] = useState<"users" | "groups">("users");
return (
<div style={{ display: "flex", flexDirection: "column", flex: 1, overflow: "hidden" }}>
<div style={{ display: "flex", borderBottom: "1px solid #e0e0e0" }}>
<button
onClick={() => setTab("users")}
style={{
flex: 1,
padding: "8px",
fontWeight: tab === "users" ? "bold" : "normal",
}}
>
Users
</button>
<button
onClick={() => setTab("groups")}
style={{
flex: 1,
padding: "8px",
fontWeight: tab === "groups" ? "bold" : "normal",
}}
>
Groups
</button>
</div>
<div style={{ flex: 1, overflow: "hidden" }}>
{tab === "users" ? (
<CometChatUsers onItemClick={onSelectUser} />
) : (
<CometChatGroups onItemClick={onSelectGroup} />
)}
</div>
</div>
);
}
Step 4: Start a one-on-one conversation
When a user is selected from the list, pass the CometChat.User object to CometChatMessageList and CometChatMessageComposer. The SDK automatically creates the conversation when the first message is sent — no explicit creation step is needed.
import { CometChat } from "@cometchat/chat-sdk-javascript";
import {
CometChatMessageList,
CometChatMessageComposer,
CometChatMessageHeader,
} from "@cometchat/chat-uikit-react";
type ChatTarget =
| { type: "user"; entity: CometChat.User }
| { type: "group"; entity: CometChat.Group };
function ChatView({ target }: { target: ChatTarget }) {
const userProp = target.type === "user" ? target.entity : undefined;
const groupProp = target.type === "group" ? target.entity : undefined;
return (
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
<CometChatMessageHeader user={userProp} group={groupProp} />
<div style={{ flex: 1, overflow: "hidden" }}>
<CometChatMessageList user={userProp} group={groupProp} />
</div>
<CometChatMessageComposer user={userProp} group={groupProp} />
</div>
);
}
Step 5: Start a group conversation
For groups, the flow is the same — select a group from CometChatGroups and pass the CometChat.Group object to the message components. If the user hasn’t joined the group yet, you can call CometChat.joinGroup() before opening the chat.
async function handleGroupSelect(group: CometChat.Group) {
// For public groups, join if not already a member
if (!group.getHasJoined()) {
try {
const joinedGroup = await CometChat.joinGroup(
group.getGuid(),
CometChat.GROUP_TYPE.PUBLIC
);
onSelectGroup(joinedGroup);
} catch (error) {
console.error("Failed to join group:", error);
}
} else {
onSelectGroup(group);
}
}
Step 6: Send the first message programmatically (optional)
If you want to send an initial message when starting a new chat (for example, an icebreaker), use the SDK directly after selecting a user.
async function sendFirstMessage(uid: string, text: string) {
const receiverType = CometChat.RECEIVER_TYPE.USER;
const textMessage = new CometChat.TextMessage(uid, text, receiverType);
try {
const sentMessage = await CometChat.sendMessage(textMessage);
console.log("Message sent:", sentMessage.getId());
} catch (error) {
console.error("Failed to send message:", error);
}
}
Complete Example
import { useState } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import {
CometChatProvider,
CometChatConversations,
CometChatUsers,
CometChatGroups,
CometChatMessageList,
CometChatMessageComposer,
CometChatMessageHeader,
} from "@cometchat/chat-uikit-react";
import "@cometchat/chat-uikit-react/styles";
type ChatTarget =
| { type: "user"; entity: CometChat.User }
| { type: "group"; entity: CometChat.Group };
function UserGroupSelector({
onSelectUser,
onSelectGroup,
}: {
onSelectUser: (user: CometChat.User) => void;
onSelectGroup: (group: CometChat.Group) => void;
}) {
const [tab, setTab] = useState<"users" | "groups">("users");
async function handleGroupSelect(group: CometChat.Group) {
if (!group.getHasJoined()) {
try {
const joinedGroup = await CometChat.joinGroup(
group.getGuid(),
CometChat.GROUP_TYPE.PUBLIC
);
onSelectGroup(joinedGroup);
} catch (error) {
console.error("Failed to join group:", error);
}
} else {
onSelectGroup(group);
}
}
return (
<div style={{ display: "flex", flexDirection: "column", flex: 1, overflow: "hidden" }}>
<div style={{ display: "flex", borderBottom: "1px solid #e0e0e0" }}>
<button
onClick={() => setTab("users")}
style={{
flex: 1,
padding: "8px",
fontWeight: tab === "users" ? "bold" : "normal",
}}
>
Users
</button>
<button
onClick={() => setTab("groups")}
style={{
flex: 1,
padding: "8px",
fontWeight: tab === "groups" ? "bold" : "normal",
}}
>
Groups
</button>
</div>
<div style={{ flex: 1, overflow: "hidden" }}>
{tab === "users" ? (
<CometChatUsers onItemClick={onSelectUser} />
) : (
<CometChatGroups onItemClick={handleGroupSelect} />
)}
</div>
</div>
);
}
function ChatView({ target }: { target: ChatTarget }) {
const userProp = target.type === "user" ? target.entity : undefined;
const groupProp = target.type === "group" ? target.entity : undefined;
return (
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
<CometChatMessageHeader user={userProp} group={groupProp} />
<div style={{ flex: 1, overflow: "hidden" }}>
<CometChatMessageList user={userProp} group={groupProp} />
</div>
<CometChatMessageComposer user={userProp} group={groupProp} />
</div>
);
}
function NewChatApp() {
const [showNewChat, setShowNewChat] = useState(false);
const [activeChat, setActiveChat] = useState<ChatTarget | null>(null);
return (
<div style={{ display: "flex", height: "100vh" }}>
<div style={{ width: "320px", borderRight: "1px solid #e0e0e0", display: "flex", flexDirection: "column" }}>
<div style={{ padding: "8px", borderBottom: "1px solid #e0e0e0" }}>
<button
onClick={() => setShowNewChat(!showNewChat)}
style={{ width: "100%", padding: "8px" }}
>
{showNewChat ? "Cancel" : "New Chat"}
</button>
</div>
{showNewChat ? (
<UserGroupSelector
onSelectUser={(user) => {
setActiveChat({ type: "user", entity: user });
setShowNewChat(false);
}}
onSelectGroup={(group) => {
setActiveChat({ type: "group", entity: group });
setShowNewChat(false);
}}
/>
) : (
<div style={{ flex: 1, overflow: "hidden" }}>
<CometChatConversations
onItemClick={(conversation) => {
const entity = conversation.getConversationWith();
if (entity instanceof CometChat.User) {
setActiveChat({ type: "user", entity });
} else if (entity instanceof CometChat.Group) {
setActiveChat({ type: "group", entity });
}
}}
/>
</div>
)}
</div>
<div style={{ flex: 1 }}>
{activeChat ? (
<ChatView target={activeChat} />
) : (
<div style={{ display: "flex", alignItems: "center", justifyContent: "center", height: "100%" }}>
<p>Select a conversation or start a new chat</p>
</div>
)}
</div>
</div>
);
}
function App() {
return (
<CometChatProvider
appId="YOUR_APP_ID"
region="YOUR_REGION"
authKey="YOUR_AUTH_KEY"
>
<NewChatApp />
</CometChatProvider>
);
}
export default App;
Next Steps