useWebVoiceAgent Hook
The useWebVoiceAgent hook is the primary interface for integrating voice navigation into React web applications. It manages the OpenAI Realtime session lifecycle and provides connection state management.
Import
import { useWebVoiceAgent } from '@navai/voice-frontend';
Type Signature
type UseWebVoiceAgentOptions = {
navigate: (path: string) => void;
moduleLoaders: NavaiFunctionModuleLoaders;
defaultRoutes: NavaiRoute[];
env?: Record<string, string | undefined>;
apiBaseUrl?: string;
routesFile?: string;
functionsFolders?: string;
modelOverride?: string;
defaultRoutesFile?: string;
defaultFunctionsFolder?: string;
};
type UseWebVoiceAgentResult = {
status: "idle" | "connecting" | "connected" | "error";
error: string | null;
isConnecting: boolean;
isConnected: boolean;
start: () => Promise<void>;
stop: () => void;
};
function useWebVoiceAgent(options: UseWebVoiceAgentOptions): UseWebVoiceAgentResult;
Basic Usage
import { useWebVoiceAgent } from '@navai/voice-frontend';
import { useNavigate } from 'react-router-dom';
const ROUTES = [
{ name: 'home', path: '/', description: 'Home page' },
{ name: 'settings', path: '/settings', description: 'Settings page' }
];
function VoiceControl() {
const navigate = useNavigate();
const { start, stop, isConnected, isConnecting, error } = useWebVoiceAgent({
navigate,
defaultRoutes: ROUTES,
moduleLoaders: {}
});
return (
<div>
<button onClick={start} disabled={isConnecting || isConnected}>
Start Voice
</button>
<button onClick={stop} disabled={!isConnected}>
Stop Voice
</button>
{isConnecting && <p>Connecting...</p>}
{error && <p>Error: {error}</p>}
</div>
);
}
Options
Required Options
navigate
(path: string) => void
required
Navigation function from your router (e.g., React Router’s useNavigate()).
Called when the agent resolves a voice navigation command.
moduleLoaders
NavaiFunctionModuleLoaders
required
Object mapping module paths to dynamic import functions. Used to load frontend functions.const moduleLoaders = {
'src/ai/functions/greet.ts': () => import('./ai/functions/greet')
};
Array of route definitions that the voice agent can navigate to.const routes = [
{
name: 'profile',
path: '/profile',
description: 'User profile page',
synonyms: ['perfil', 'account']
}
];
Optional Options
env
Record<string, string | undefined>
Environment variables object. Useful for passing runtime configuration.env: {
NAVAI_API_URL: 'https://api.example.com',
NAVAI_ROUTES_FILE: 'src/custom-routes.ts'
}
apiBaseUrl
string
default:"http://localhost:3000"
Base URL for the NAVAI backend API. Overrides NAVAI_API_URL from env.
routesFile
string
default:"src/ai/routes.ts"
Path to custom routes module. Resolved at runtime if found in moduleLoaders.
functionsFolders
string
default:"src/ai/functions-modules"
Comma-separated paths or globs for function modules. Supports wildcards:
src/ai/functions-modules - exact folder
src/ai/functions-modules/... - recursive
src/*/functions - glob pattern
Override the OpenAI Realtime model. Can also be set via NAVAI_REALTIME_MODEL env var.modelOverride: 'gpt-4o-realtime-preview-2024-12-17'
defaultRoutesFile
string
default:"src/ai/routes.ts"
Default path used for route file resolution.
defaultFunctionsFolder
string
default:"src/ai/functions-modules"
Default path used for function discovery.
Return Values
status
'idle' | 'connecting' | 'connected' | 'error'
Current connection state of the voice agent.
Error message if status is ‘error’, otherwise null.
Convenience boolean: status === 'connecting'
Convenience boolean: status === 'connected'
Async function to start the voice session. Performs the following:
- Resolves runtime configuration (routes, functions)
- Requests client secret from backend API
- Lists backend functions
- Builds the RealtimeAgent with tools
- Connects to OpenAI Realtime API
Sets status to ‘error’ and populates error message on failure.
Synchronously closes the voice session and resets status to ‘idle’.
Connection Lifecycle
Idle State
Initial state. Call start() to begin connection.
Connecting State
The hook:
- Resolves runtime config (routes, functions)
- Fetches client secret from backend
- Lists available backend functions
- Builds RealtimeAgent with navigation and function tools
- Connects to OpenAI Realtime API
Connected State
Voice agent is active and listening. User can speak navigation commands and function calls.
Error State
Connection failed. Check the error field for details. Call start() to retry.
Stopped
Call stop() to close the session and return to idle state.
Complete Example
import { useWebVoiceAgent } from '@navai/voice-frontend';
import { useNavigate } from 'react-router-dom';
import { useState } from 'react';
// Define routes
const APP_ROUTES = [
{
name: 'home',
path: '/',
description: 'Home page',
synonyms: ['inicio', 'main']
},
{
name: 'dashboard',
path: '/dashboard',
description: 'Analytics dashboard'
},
{
name: 'settings',
path: '/settings',
description: 'User settings',
synonyms: ['preferences', 'config']
}
];
// Module loaders for functions
const moduleLoaders = {
'src/ai/functions/greet.ts': () => import('./ai/functions/greet'),
'src/ai/functions/search.ts': () => import('./ai/functions/search')
};
function VoiceNavigationButton() {
const navigate = useNavigate();
const [showDebug, setShowDebug] = useState(false);
const {
start,
stop,
status,
isConnecting,
isConnected,
error
} = useWebVoiceAgent({
navigate,
defaultRoutes: APP_ROUTES,
moduleLoaders,
apiBaseUrl: process.env.REACT_APP_NAVAI_API_URL,
env: {
NAVAI_REALTIME_MODEL: process.env.REACT_APP_REALTIME_MODEL
}
});
const handleToggle = () => {
if (isConnected) {
stop();
} else {
start();
}
};
return (
<div className="voice-control">
<button
onClick={handleToggle}
disabled={isConnecting}
className={isConnected ? 'active' : ''}
>
{isConnecting && 'Connecting...'}
{isConnected && '🎤 Listening'}
{status === 'idle' && '🎤 Start Voice'}
{status === 'error' && '⚠️ Retry'}
</button>
<button onClick={() => setShowDebug(!showDebug)}>
Debug
</button>
{showDebug && (
<div className="debug-panel">
<p>Status: {status}</p>
{error && <p className="error">Error: {error}</p>}
</div>
)}
</div>
);
}
export default VoiceNavigationButton;
Error Handling
The hook handles errors during connection and returns them in the error field:
const { start, error, status } = useWebVoiceAgent(options);
useEffect(() => {
if (status === 'error') {
console.error('Voice agent error:', error);
// Optionally retry after delay
setTimeout(() => start(), 5000);
}
}, [status, error, start]);
Cleanup
The hook automatically cleans up on unmount:
// Internal implementation (for reference)
useEffect(() => {
return () => {
stop(); // Closes session on component unmount
};
}, [stop]);
Warnings
The hook emits warnings to the console for configuration issues:
- Route file not found (falls back to defaultRoutes)
- Function folder doesn’t match any modules
- Backend function name conflicts
- Invalid function names
- Function loading errors
Warnings are informational and don’t prevent the agent from working. Check the console during development to ensure your configuration is correct.