React
React hooks for voice AI integration
Installation
npm install @ai-chans/sdk-react
Note:
If you're using Next.js App Router, components that use useVoiceAgent must be client components. Add "use client" at the top of the file.
useVoiceAgent Hook
The recommended way to add voice to React apps.
import { useVoiceAgent } from "@ai-chans/sdk-react"
function VoiceChat() { const { state, isConnected, error, connect, disconnect } = useVoiceAgent( { agentToken: "agt_xxx" }, { onTranscript: (text) => console.log("User:", text), onResponse: (text) => console.log("Agent:", text), } )
const handleClick = () => { if (state === "idle") { connect() } else { disconnect() } }
return ( <div> {error && <p style={{ color: "red" }}>{error}</p>} <button onClick={handleClick} disabled={state === "connecting"}> {state === "idle" ? "Start" : state === "connecting" ? "Connecting..." : "Stop"} </button> <p>Status: {state}</p> </div> )}
Options
interface UseVoiceAgentOptions { agentToken: string // Required: Agent token from dashboard apiUrl?: string // Optional: API URL (default: https://api.chans.ai) userId?: string // Optional: User ID for conversation segmentation}
Callbacks
interface UseVoiceAgentCallbacks { onStateChange?: (state: ChansState) => void onConnected?: () => void onAgentConnected?: (agent: AgentInfo) => void onAgentDisconnected?: () => void onTranscript?: (text: string) => void // Interim transcription onUserTurnComplete?: (text: string) => void // Final transcription onResponse?: (text: string) => void // Agent response onDisconnected?: () => void onError?: (error: Error) => void}
Return Value
interface UseVoiceAgentReturn { state: ChansState // Current connection state isConnected: boolean // Whether connected error: string | null // Error message if any connect: () => Promise<void> // Start connection disconnect: () => Promise<void> // End connection}
Full Example
import { useState } from "react"import { useVoiceAgent, type ChansState } from "@ai-chans/sdk-react"
interface Message { role: "user" | "agent" text: string}
function VoiceChat() { const [messages, setMessages] = useState<Message[]>([])
const { state, error, connect, disconnect } = useVoiceAgent( { agentToken: process.env.NEXT_PUBLIC_AGENT_TOKEN!, apiUrl: process.env.NEXT_PUBLIC_API_URL, }, { onUserTurnComplete: (text) => { setMessages((prev) => [...prev, { role: "user", text }]) }, onResponse: (text) => { setMessages((prev) => [...prev, { role: "agent", text }]) }, onError: (err) => { console.error("Voice error:", err) }, } )
return ( <div> <h2>Voice Chat</h2>
{error && <div className="error">{error}</div>}
<div className="messages"> {messages.map((msg, i) => ( <div key={i} className={msg.role}> <strong>{msg.role}:</strong> {msg.text} </div> ))} </div>
<button onClick={state === "idle" ? connect : disconnect} disabled={state === "connecting"} > {getButtonLabel(state)} </button> </div> )}
function getButtonLabel(state: ChansState): string { switch (state) { case "idle": return "Start Conversation" case "connecting": return "Connecting..." case "waiting": return "Waiting for agent..." case "ready": return "Listening... (click to stop)" case "processing": return "Processing..." case "speaking": return "Agent speaking..." default: return "Stop" }}
States
The hook returns a state value indicating the current connection status:
| State | Description |
|---|---|
idle | Not connected |
connecting | Establishing connection |
waiting | Connected, waiting for agent |
ready | Agent connected, listening for speech |
processing | User spoke, waiting for response |
speaking | Agent is responding |
error | An error occurred |
Next
- JavaScript - Core SDK reference
- Quick Start - Get started guide