React
React hooks for voice AI integration
Installation
npm install @ai-chans/sdk-react
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