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

# New Chat Creation

> Start new one-on-one or group conversations by selecting users or groups from a list.

## 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

* Completed the [Integration Guide](/ui-kit/react/v7/integration-react) guide
* A running `CometChatProvider` setup with valid credentials
* Familiarity with [CometChatUsers](/ui-kit/react/v7/components/users) and [CometChatGroups](/ui-kit/react/v7/components/groups) components

## 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.

```tsx App.tsx theme={null}
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.

```tsx NewChatApp.tsx theme={null}
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.

```tsx UserGroupSelector.tsx theme={null}
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.

```tsx ChatView.tsx theme={null}
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.

```tsx theme={null}
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.

```tsx theme={null}
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

```tsx NewChatApp.tsx theme={null}
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

* [CometChatUsers](/ui-kit/react/v7/components/users) — customize the user list appearance and filtering
* [CometChatGroups](/ui-kit/react/v7/components/groups) — browse and manage groups
* [Conversations](/ui-kit/react/v7/components/conversations) — display existing conversations
* [Group Chat Setup](/ui-kit/react/v7/guide-group-chat-setup) — create and configure group conversations
