The One‑to‑One/Group chat layout focuses on a single conversation, ideal for support chats and private messaging. This guide uses Astro with React islands and the CometChat React UI Kit.
If you already have the sample astro-one-to-one-chat project, open it instead.
2
Add React and install CometChat UI Kit
Report incorrect code
Copy
Ask AI
npx astro add reactnpm i @cometchat/chat-uikit-react react react-dom
Add required environment variables to .env:
Report incorrect code
Copy
Ask AI
PUBLIC_COMETCHAT_APP_ID=your_app_idPUBLIC_COMETCHAT_REGION=your_regionPUBLIC_COMETCHAT_AUTH_KEY=your_auth_key# Login user and the peer for one-to-onePUBLIC_COMETCHAT_LOGIN_UID=cometchat-uid-3PUBLIC_COMETCHAT_TARGET_UID=cometchat-uid-1
Use Auth Tokens in production instead of Auth Keys.
3
Initialize CometChat (src/lib/cometchat-init.js)
Create src/lib/cometchat-init.js used by the island to initialize the UI Kit and handle login.
src/lib/cometchat-init.js
Report incorrect code
Copy
Ask AI
import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react";const APP_ID = import.meta.env.PUBLIC_COMETCHAT_APP_ID;const REGION = import.meta.env.PUBLIC_COMETCHAT_REGION;const AUTH_KEY = import.meta.env.PUBLIC_COMETCHAT_AUTH_KEY;export async function initCometChat() { if (!APP_ID || !REGION || !AUTH_KEY) { throw new Error("Missing PUBLIC_COMETCHAT_* env vars."); } const settings = new UIKitSettingsBuilder() .setAppId(APP_ID) .setRegion(REGION) .setAuthKey(AUTH_KEY) // use Auth Tokens in prod .subscribePresenceForAllUsers() .build(); await CometChatUIKit.init(settings);}export async function ensureLogin(uid) { const existing = await CometChatUIKit.getLoggedinUser(); if (!existing) await CometChatUIKit.login(uid);}
4
Build the React island (src/components/OneToOneChat.jsx)
This component initializes CometChat, logs in the desired user, and loads a single peer (user or group) to chat with.
src/components/OneToOneChat.jsx
Report incorrect code
Copy
Ask AI
import { useEffect, useState } from "react";import { CometChatUIKit, CometChatMessageHeader, CometChatMessageList, CometChatMessageComposer,} from "@cometchat/chat-uikit-react";import "@cometchat/chat-uikit-react/css-variables.css";import { initCometChat, ensureLogin } from "../lib/cometchat-init.js";// current user + peerconst LOGIN_UID = import.meta.env.PUBLIC_COMETCHAT_LOGIN_UID; // e.g., cometchat-uid-3const TARGET_UID = import.meta.env.PUBLIC_COMETCHAT_TARGET_UID; // e.g., cometchat-uid-1export default function OneToOneChat() { const [phase, setPhase] = useState("boot"); // boot | ready | error const [errorMsg, setErrorMsg] = useState(""); const [peer, setPeer] = useState(null); // CometChat.User useEffect(() => { let cancelled = false; (async () => { try { if (!LOGIN_UID || !TARGET_UID) { throw new Error("Missing PUBLIC_COMETCHAT_LOGIN_UID or PUBLIC_COMETCHAT_TARGET_UID."); } // 1) Initialize CometChat await initCometChat(); // 2) Handle user switching - logout if different user try { const currentUser = await CometChatUIKit.getLoggedinUser(); if (currentUser && currentUser.uid !== LOGIN_UID) { await CometChatUIKit.logout(); } } catch (error) { // No existing user session } // 3) Ensure logged in as correct user await ensureLogin(LOGIN_UID); // 4) Fetch the peer user const { CometChat } = await import("@cometchat/chat-sdk-javascript"); const u = await CometChat.getUser(TARGET_UID); if (!cancelled) { setPeer(u); setPhase("ready"); } } catch (e) { if (!cancelled) { setErrorMsg(String(e?.message || e)); setPhase("error"); } } })(); return () => { cancelled = true; }; }, [LOGIN_UID, TARGET_UID]); // Re-run when these change if (phase === "boot") return ( <div style={{ padding: 16 }}> <div>Loading…</div> </div> ); if (phase === "error") return ( <div style={{ padding: 16, color: "crimson" }}> <div><b>Error:</b> {errorMsg}</div> </div> ); if (!peer) return <div className="cc-one-to-one__empty">Invalid target user.</div>; return ( <div className="cc-one-to-one"> <CometChatMessageHeader user={peer} /> <div className="cc-one-to-one__list-slot"> <CometChatMessageList user={peer} /> </div> <CometChatMessageComposer user={peer} /> </div> );}
5
Render the page (src/pages/index.astro)
Import the island and styles, then hydrate on the client.
src/pages/index.astro
Report incorrect code
Copy
Ask AI
---import OneToOneChat from "../components/OneToOneChat.jsx";import "../styles/globals.css"; // your existing base CSS (optional, recommended)import "../styles/one-to-one.css"; // the file from this setup---<html lang="en"> <head> <meta charset="utf-8" /> <title>One-to-One Chat</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <!-- client-only island; CometChat needs browser APIs --> <OneToOneChat client:only="react" /> </body></html>
6
Run and verify
Report incorrect code
Copy
Ask AI
npm run dev
Set PUBLIC_COMETCHAT_LOGIN_UID and PUBLIC_COMETCHAT_TARGET_UID then verify messages appear for the selected peer.
To load a group instead of a user, fetch it with the SDK and pass it to the UI Kit components.
Report incorrect code
Copy
Ask AI
const { CometChat } = await import("@cometchat/chat-sdk-javascript");const group = await CometChat.getGroup("YOUR_GROUP_ID");// Then render header, list, composer with group prop instead of user
When switching between user and group, keep only one of user or group props set at a time.
Ensure the component is rendered as a React island (client:only=\"react\").
Missing credentials
Verify .env contains PUBLIC_COMETCHAT_APP_ID, PUBLIC_COMETCHAT_REGION, PUBLIC_COMETCHAT_AUTH_KEY, and both PUBLIC_COMETCHAT_LOGIN_UID and PUBLIC_COMETCHAT_TARGET_UID.
Wrong user appears
The island logs out if a different user session is active, then logs in with PUBLIC_COMETCHAT_LOGIN_UID.