useChat
Your interface, your customers, your support crew. This hook connects a customer to chat and keeps authentication state available to your React components.
Give chat a home.
Wrap the chat interface in CStarChatProvider. Hooks inside it share that customer's
client.
import { CStarChatProvider } from '@cstar.help/react';
import { ChatHeader } from './ChatHeader';
export function Support({ accountKey }: { accountKey: string }) {
return (
<CStarChatProvider key={accountKey} teamSlug="your-team-slug">
<ChatHeader />
</CStarChatProvider>
);
} Mount this tree only for the signed-in app session. Make accountKey change when the customer,
team or sign-in session changes, including signing back in as the same person. Remove the tree on
app sign-out. The provider creates one client from its initial configuration and disconnects when
unmounted; changing its props alone does not replace that client.
Connect the customer.
This example uses your app's existing sign-in. The button asks your server for a signed identity, then connects to cStar. A failed request leaves the customer with a useful next step.
import { useEffect, useRef, useState } from 'react';
import { useChat } from '@cstar.help/react';
export function ChatHeader() {
const { isAuthenticated, identify, disconnect } = useChat();
const [busy, setBusy] = useState(false);
const [feedback, setFeedback] = useState('');
const activeRequest = useRef<AbortController | null>(null);
useEffect(() => () => {
activeRequest.current?.abort();
activeRequest.current = null;
}, []);
async function connect() {
if (activeRequest.current) return;
const request = new AbortController();
activeRequest.current = request;
setBusy(true);
setFeedback('');
try {
// Your authenticated server signs this customer's identity.
const response = await fetch('/api/cstar-auth', {
signal: request.signal,
cache: 'no-store'
});
if (!response.ok) throw new Error('Identity unavailable');
const { customer, signature } = await response.json();
if (request.signal.aborted) return;
await identify(customer, signature);
} catch {
if (!request.signal.aborted) {
setFeedback("Couldn't connect. Please try again.");
}
} finally {
if (activeRequest.current === request) {
activeRequest.current = null;
setBusy(false);
}
}
}
return (
<section aria-label="Customer support">
{isAuthenticated ? (
<>
<p>You're connected. Your crew is here to help.</p>
<button type="button" onClick={disconnect}>Disconnect chat</button>
</>
) : (
<button type="button" disabled={busy} onClick={connect}>
{busy ? 'Connecting…' : 'Connect to support'}
</button>
)}
<p role="status">{feedback}</p>
</section>
);
} /api/cstar-auth is a route you build on your server. It must use your verified app
session to sign only that customer's identity and return { customer, signature } with Cache-Control: no-store. Keep the identity secret out of browser code. Follow
the HMAC signing example for the exact fields and timestamp.
What the hook returns
isAuthenticatedandauthModedescribe the client authentication state.authModeisnullbefore authentication or after disconnect.identify(customer, signature)returns a promise with the verified customer and session response.loginWithCredentials({ email, password })uses an existing cStar customer account.loginWithSession({ accessToken })uses a customer token issued by cStar's auth service, not an unrelated auth provider.disconnect()clears this chat client and its subscriptions. It does not sign the customer out of your app or revoke their identity-provider session.errorholds the latest authentication error. Authentication methods also reject, so catch them in event handlers.isRealtimeReadyis the hook's realtime readiness flag. Messages can use polling when realtime is unavailable; don't block chat solely on this flag.isIdentifiedis a deprecated alias forisAuthenticated. Prefer the newer name.
The hook does not return a customer profile or a client field. Keep display details
from your own authenticated session or the authentication result. To access the underlying
client, call the separate useChatClient() hook inside the provider.
Keep the conversation going.
Use useTickets for conversations and useMessages for a selected thread. The customer chat guide explains authentication choices, preserving a draft after a failed response and cleaning up subscriptions.