Overview
The useWebVoiceAgent hook manages the complete lifecycle of a Navai voice agent in React applications. It handles connection management, authentication, function loading, and real-time communication.
Import
import { useWebVoiceAgent } from '@navai/voice-frontend';
Type Signature
function useWebVoiceAgent(
options: UseWebVoiceAgentOptions
): UseWebVoiceAgentResult
Parameters
options
UseWebVoiceAgentOptions
required
Configuration options for the voice agentnavigate
(path: string) => void
required
Navigation function called when agent navigates to a route// React Router v6
navigate: (path) => router.push(path)
// Next.js
navigate: (path) => router.push(path)
moduleLoaders
NavaiFunctionModuleLoaders
required
Map of module paths to dynamic import functionsmoduleLoaders: {
'./functions/search.ts': () => import('./functions/search'),
'./functions/profile.ts': () => import('./functions/profile')
}
Array of route definitions for navigationdefaultRoutes: [
{
name: 'home',
path: '/',
description: 'Home page',
synonyms: ['main', 'dashboard']
},
{
name: 'profile',
path: '/profile',
description: 'User profile page'
}
]
env
Record<string, string | undefined>
Environment variables (optional)env: {
NAVAI_API_URL: 'https://api.example.com'
}
Backend API base URL (defaults to http://localhost:3000)
Path to routes configuration file
Comma-separated list of function folders
OpenAI model override (e.g., gpt-4o-realtime-preview-2024-12-17)
Path to default routes file
Default functions folder path
Return Value
Current connection status: "idle" | "connecting" | "connected" | "error"
Error message if status is "error", otherwise null
true when status is "connecting"
true when status is "connected"
start
() => Promise<void>
required
Async function to start the voice agent connection
- Creates backend client secret
- Loads backend functions
- Builds agent with all functions and routes
- Establishes Realtime connection
- Updates status to
"connected" on success or "error" on failure
Function to stop the voice agent connection
- Closes the Realtime session
- Resets status to
"idle"
- Cleans up session reference
Examples
Basic Usage
import { useWebVoiceAgent } from '@navai/voice-frontend';
import { useNavigate } from 'react-router-dom';
function VoiceControl() {
const navigate = useNavigate();
const { status, error, start, stop } = useWebVoiceAgent({
navigate,
moduleLoaders: {
'./functions/search.ts': () => import('./functions/search')
},
defaultRoutes: [
{ name: 'home', path: '/', description: 'Home page' }
]
});
return (
<div>
<button onClick={status === 'connected' ? stop : start}>
{status === 'connected' ? 'Stop' : 'Start'} Voice
</button>
{error && <p>Error: {error}</p>}
</div>
);
}
With Loading State
function VoiceButton() {
const { status, isConnecting, isConnected, start, stop } = useWebVoiceAgent({
navigate: (path) => router.push(path),
moduleLoaders: {
'./functions/search.ts': () => import('./functions/search')
},
defaultRoutes: []
});
return (
<button onClick={isConnected ? stop : start} disabled={isConnecting}>
{isConnecting && 'Connecting...'}
{isConnected && 'Stop Voice'}
{status === 'idle' && 'Start Voice'}
{status === 'error' && 'Retry'}
</button>
);
}
With Custom Backend URL
const { start, stop } = useWebVoiceAgent({
navigate,
moduleLoaders,
defaultRoutes,
apiBaseUrl: 'https://api.example.com',
env: {
NAVAI_API_URL: 'https://api.example.com'
}
});
With Model Override
const { start, stop } = useWebVoiceAgent({
navigate,
moduleLoaders,
defaultRoutes,
modelOverride: 'gpt-4o-realtime-preview-2024-12-17'
});
With Multiple Function Modules
const { start, stop } = useWebVoiceAgent({
navigate,
moduleLoaders: {
'./functions/search.ts': () => import('./functions/search'),
'./functions/profile.ts': () => import('./functions/profile'),
'./functions/settings.ts': () => import('./functions/settings'),
'./functions/analytics.ts': () => import('./functions/analytics')
},
defaultRoutes: [
{ name: 'search', path: '/search', description: 'Search page' },
{ name: 'profile', path: '/profile', description: 'User profile' },
{ name: 'settings', path: '/settings', description: 'Settings' }
]
});
State Flow
┌──────┐ start() ┌────────────┐ success ┌───────────┐
│ idle ├──────────►│ connecting ├──────────►│ connected │
└──┬───┘ └─────┬──────┘ └─────┬─────┘
│ │ │
│ │ error │
│ ▼ │
│ ┌───────┐ │
│◄─────────────────┤ error │ │
│ retry └───────┘ │
│ │
│◄──────────────────────────────────────────────┘
stop()
Lifecycle
-
Initialization (
idle)
- Hook mounts with idle status
- Configuration is memoized
- Backend client is created
-
Connection (
connecting)
start() is called
- Backend client secret is created
- Backend functions are loaded
- Agent is built with all functions and routes
- Realtime session is established
-
Active (
connected)
- Voice agent is active
- User can interact via voice
- Functions and navigation work
-
Error (
error)
- Connection or function execution failed
- Error message is available in
error field
- Can retry by calling
start() again
-
Cleanup
stop() is called or component unmounts
- Session is closed
- Status returns to
idle
Error Handling
The hook handles errors at multiple levels:
function VoiceWithErrorHandling() {
const { status, error, start, stop } = useWebVoiceAgent({
navigate,
moduleLoaders,
defaultRoutes
});
useEffect(() => {
if (status === 'error') {
console.error('Voice agent error:', error);
// Optionally log to error tracking service
}
}, [status, error]);
return (
<div>
{status === 'error' && (
<div className="error">
<p>{error}</p>
<button onClick={start}>Retry</button>
</div>
)}
<button onClick={status === 'connected' ? stop : start}>
{status === 'connected' ? 'Stop' : 'Start'}
</button>
</div>
);
}
Warnings
The hook emits console warnings for:
- Runtime configuration warnings
- Backend function loading issues
- Function name conflicts
- Invalid tool names
- Duplicate functions
Warnings are logged to console but don’t prevent the agent from working.