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

# Conversation List + Message View

> Build a two-panel conversation list + message view layout in Astro with CometChat UI Kit.

<Accordion title="AI Integration Quick Reference">
  | Field        | Value                                                                                                  |
  | ------------ | ------------------------------------------------------------------------------------------------------ |
  | Package      | `@cometchat/chat-uikit-react`                                                                          |
  | Framework    | Astro                                                                                                  |
  | Components   | `CometChatConversations`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` |
  | Layout       | Two-panel — conversation list (left) + message view (right)                                            |
  | Prerequisite | Complete [Astro Integration](/ui-kit/react/integration-astro) first                                    |
  | SSR          | React island with `client:only="react"` directive                                                      |
  | Pattern      | WhatsApp Web, Slack, Microsoft Teams                                                                   |
</Accordion>

This guide builds a two-panel chat layout — conversation list on the left, messages on the right. Users click a conversation to open it.

This assumes you've already completed [Astro Integration](/ui-kit/react/integration-astro) (project created, UI Kit installed, init + login working).

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-agent-in-group-react-v6/HFcVeMLV3mvaKsLs/images/two_panel_layout_without_tabs_react_v7.png?fit=max&auto=format&n=HFcVeMLV3mvaKsLs&q=85&s=23ba47fe83ebe31c88f5110d7eaba85b" width="1440" height="800" data-path="images/two_panel_layout_without_tabs_react_v7.png" />
</Frame>

***

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

***

## Full Code

Create a React island component with the chat UI, then render it in an Astro page with `client:only="react"`.

```tsx title="src/components/ConversationChat.tsx" theme={null}
import { useEffect, useState } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import {
  CometChatUIKit,
  UIKitSettingsBuilder,
  CometChatProvider,
  CometChatConversations,
  CometChatMessageHeader,
  CometChatMessageList,
  CometChatMessageComposer,
} from "@cometchat/chat-uikit-react";

export default function ConversationChat() {
  const [ready, setReady] = useState(false);
  const [selectedUser, setSelectedUser] = useState<CometChat.User | undefined>(undefined);
  const [selectedGroup, setSelectedGroup] = useState<CometChat.Group | undefined>(undefined);

  useEffect(() => {
    const settings = new UIKitSettingsBuilder()
      .setAppId("YOUR_APP_ID")
      .setRegion("YOUR_REGION")
      .setAuthKey("YOUR_AUTH_KEY")
      .subscribePresenceForAllUsers()
      .build();

    CometChatUIKit.init(settings).then(async () => {
      await CometChatUIKit.login("cometchat-uid-1");
      setReady(true);
    });
  }, []);

  if (!ready) return <div>Loading chat...</div>;

  const handleConversationClick = (conversation: CometChat.Conversation) => {
    const entity = conversation.getConversationWith();
    if (conversation.getConversationType() === "user") {
      setSelectedUser(entity as CometChat.User);
      setSelectedGroup(undefined);
    } else {
      setSelectedGroup(entity as CometChat.Group);
      setSelectedUser(undefined);
    }
  };

  return (
    <CometChatProvider>
      <div style={{
        display: "flex",
        height: "100vh",
        width: "100%",
      }}>
        <div style={{
          width: 360,
          height: "100%",
          borderRight: "1px solid #eee",
          overflow: "hidden",
          display: "flex",
          flexDirection: "column",
        }}>
          <CometChatConversations onItemClick={handleConversationClick} />
        </div>

        {selectedUser || selectedGroup ? (
          <div style={{
            flex: 1,
            height: "100%",
            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: "flex",
            justifyContent: "center",
            alignItems: "center",
            background: "#f5f5f5",
            color: "#727272",
            font: "400 14px Roboto, sans-serif",
          }}>
            Select a conversation to start chatting
          </div>
        )}
      </div>
    </CometChatProvider>
  );
}
```

```astro title="src/pages/chat.astro" theme={null}
---
import ConversationChat from '../components/ConversationChat.tsx';
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Chat</title>
  </head>
  <body style="margin: 0;">
    <ConversationChat client:only="react" />
  </body>
</html>
```

***

## How It Works

1. **`client:only="react"`** tells Astro to skip server-rendering and hydrate the component entirely on the client. This is required because CometChat uses browser APIs.
2. **React island** — the CometChat UI lives in a self-contained React component. Astro handles the page shell, React handles the interactive chat.
3. **CometChatProvider** wraps the entire tree — it supplies theme, locale, and event context to all CometChat components.
4. **CometChatConversations** renders the sidebar list. When a user clicks a conversation, `onItemClick` fires with the `Conversation` object.
5. **handleConversationClick** extracts the `User` or `Group` from the conversation and stores it in state.
6. **Message components** (`MessageHeader`, `MessageList`, `MessageComposer`) receive either `user` or `group` as a prop — never both at the same time.

***

## Run

```bash theme={null}
npm run dev
```

Open `http://localhost:4321/chat`. You should see the conversation list on the left. Click any conversation to load messages on the right.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="One-to-One / Group Chat" icon="message" href="/ui-kit/react/astro-one-to-one-chat">
    Single chat window without a sidebar
  </Card>

  <Card title="Tab-Based Chat" icon="table-columns" href="/ui-kit/react/astro-tab-based-chat">
    Tabbed navigation with Chats, Calls, Users
  </Card>

  <Card title="Components Overview" icon="grid-2" href="/ui-kit/react/components-overview">
    Browse all prebuilt UI components
  </Card>

  <Card title="Theming" icon="paintbrush" href="/ui-kit/react/theming">
    Customize colors, fonts, and styles
  </Card>
</CardGroup>
