The DialNexa React SDK is currently in development. This page will be updated when the SDK is released.
What the React SDK Will Support
When available, the React SDK (@dialnexa/react) will allow you to embed voice agent calls directly in web applications without managing WebRTC or call lifecycle state yourself. Planned capabilities include:
- Web call initiation: Start and end a voice call to a DialNexa agent from a browser, using WebRTC for audio transport
- Call state management: A
useDialNexa hook (or similar) exposing call status (idle, connecting, connected, ended), mute controls, and call duration
- Live transcript: Access to the real-time conversation transcript as the call progresses
- Dynamic variables: Pass caller context (user name, account ID, etc.) at call start to inject into the agent prompt
- Event callbacks:
onCallStarted, onCallEnded, onCallError, and onTranscriptUpdate handlers
- Authentication: Support for both a public key (for open widgets) and a short-lived signed token (for authenticated user flows where a backend generates the token)
- Audio device selection: Let users pick their microphone and speaker
The SDK will work with React 17 and later, and will use standard WebRTC, which is supported in Chrome, Firefox, Safari, and Edge on desktop and mobile.
Web Calls Today
Web calls are already supported in DialNexa via the web call widget that can be embedded in any web page. While the full React SDK is not yet available, you can use the embeddable widget as a stopgap for simple web call integrations.
See Web Call for the current embedding approach.
Get Notified
This page will be updated with installation instructions, API reference, and code examples when the React SDK reaches public release. If you have specific use cases or requirements you would like the SDK to support, contact support@dialnexa.com.
Related Pages
The DialNexa React SDK lets you embed a voice AI agent directly in a web application. Users can connect to your agent from any browser - no phone number required. Web calls use WebRTC for audio transport and connect to the same agent infrastructure as phone calls.
Common use cases:
- Customer support widgets on your website
- AI-powered onboarding flows
- In-app voice assistants
- Demos and prototypes
Installation
npm install @dialnexa/react
# or
yarn add @dialnexa/react
# or
pnpm add @dialnexa/react
The SDK requires React 17 or later. Peer dependencies include react and react-dom.
Quick Start
Here is the minimal setup to embed a voice agent call button in your React app:
import { useDialNexa } from '@dialnexa/react';
export function CallButton() {
const { startCall, endCall, callStatus } = useDialNexa({
agentId: 'your-agent-id',
// For production, generate a signed token server-side.
// See Authentication below.
publicKey: 'your-public-key',
});
return (
<div>
<p>Status: {callStatus}</p>
{callStatus === 'idle' && (
<button onClick={startCall}>Talk to our AI agent</button>
)}
{callStatus === 'connected' && (
<button onClick={endCall}>End call</button>
)}
</div>
);
}
Authentication
Never expose your DialNexa API key in client-side code. The React SDK uses a separate public key or a short-lived signed token for web call authentication.
Option 1: Public key (simple, limited security)
A public key is a non-secret identifier that allows web call initiation only (cannot access other API resources). Suitable for public-facing widgets where any visitor can start a call.
Generate a public key in Settings → API Keys → New Web Call Key.
Option 2: Signed token (recommended for production)
For production deployments, generate a short-lived JWT server-side and pass it to the SDK. This lets you control who can start a call (e.g., only authenticated users) and embed per-call metadata.
Server-side (Node.js example):
import { DialNexa } from '@dialnexa/node';
const client = new DialNexa({ apiKey: process.env.DIALNEXA_API_KEY });
// In your API route handler:
app.get('/api/dialnexa-token', authenticateUser, async (req, res) => {
const token = await client.webCalls.createToken({
agentId: 'your-agent-id',
expiresIn: 3600, // 1 hour
metadata: {
userId: req.user.id,
userName: req.user.name,
},
});
res.json({ token });
});
Client-side:
import { useDialNexa } from '@dialnexa/react';
function CallButton() {
const [token, setToken] = useState<string | null>(null);
useEffect(() => {
fetch('/api/dialnexa-token')
.then(r => r.json())
.then(data => setToken(data.token));
}, []);
const { startCall, endCall, callStatus } = useDialNexa({
agentId: 'your-agent-id',
token: token ?? undefined,
});
// ...
}
The useDialNexa Hook
The primary interface for the SDK is the useDialNexa hook.
Configuration Options
interface DialNexaConfig {
agentId: string; // Required: your agent's ID
publicKey?: string; // For public-key authentication
token?: string; // For signed-token authentication
onCallStarted?: () => void;
onCallEnded?: (reason: CallEndReason) => void;
onCallError?: (error: DialNexaError) => void;
onTranscriptUpdate?: (transcript: TranscriptTurn[]) => void;
audioInputDeviceId?: string; // Override default microphone
audioOutputDeviceId?: string; // Override default speaker
}
Returned Values
interface DialNexaHookReturn {
startCall: () => Promise<void>;
endCall: () => void;
callStatus: CallStatus; // 'idle' | 'connecting' | 'connected' | 'ended' | 'error'
isMuted: boolean;
mute: () => void;
unmute: () => void;
transcript: TranscriptTurn[];
error: DialNexaError | null;
callDuration: number; // Seconds elapsed since call started
}
Handling Call Events
Use callbacks in the config or the returned state values to respond to call events:
import { useDialNexa, CallStatus, DialNexaError } from '@dialnexa/react';
function VoiceWidget() {
const { startCall, endCall, callStatus, isMuted, mute, unmute, transcript, error } = useDialNexa({
agentId: 'your-agent-id',
publicKey: 'your-public-key',
onCallStarted: () => {
console.log('Call connected');
analytics.track('web_call_started');
},
onCallEnded: (reason) => {
console.log('Call ended:', reason);
// reason: 'user_hangup' | 'agent_hangup' | 'max_duration' | 'error'
},
onCallError: (error) => {
console.error('Call error:', error.code, error.message);
},
onTranscriptUpdate: (turns) => {
// Called after each new turn in the conversation
console.log('Latest turn:', turns[turns.length - 1]);
},
});
if (error) {
return <div className="error">Call failed: {error.message}</div>;
}
return (
<div className="voice-widget">
<div className="status">
{callStatus === 'connecting' && <span>Connecting...</span>}
{callStatus === 'connected' && <span>Connected ({callStatus})</span>}
{callStatus === 'idle' && <span>Ready</span>}
</div>
<div className="controls">
{callStatus === 'idle' && (
<button onClick={startCall}>Start Call</button>
)}
{callStatus === 'connected' && (
<>
<button onClick={endCall}>End Call</button>
<button onClick={isMuted ? unmute : mute}>
{isMuted ? 'Unmute' : 'Mute'}
</button>
</>
)}
</div>
<div className="transcript">
{transcript.map((turn, i) => (
<div key={i} className={`turn turn--${turn.speaker}`}>
<strong>{turn.speaker === 'agent' ? 'Agent' : 'You'}:</strong> {turn.text}
</div>
))}
</div>
</div>
);
}
Dynamic Variables
Pass dynamic variables to the agent at call start. These are injected into the agent’s prompt using {{variable_name}} syntax:
const { startCall } = useDialNexa({
agentId: 'your-agent-id',
publicKey: 'your-public-key',
});
// Start the call with variables
await startCall({
variables: {
user_name: 'Priya Sharma',
account_id: 'ACC-12345',
plan: 'Professional',
},
});
In the agent’s system prompt:
You are a support agent for DialNexa. You are speaking with {{user_name}}
(account: {{account_id}}, plan: {{plan}}).
Audio Device Selection
To let users select their microphone and speaker:
import { useDialNexa, useAudioDevices } from '@dialnexa/react';
function CallWithDeviceSelector() {
const { audioInputDevices, audioOutputDevices } = useAudioDevices();
const [inputDevice, setInputDevice] = useState<string>();
const [outputDevice, setOutputDevice] = useState<string>();
const { startCall, endCall, callStatus } = useDialNexa({
agentId: 'your-agent-id',
publicKey: 'your-public-key',
audioInputDeviceId: inputDevice,
audioOutputDeviceId: outputDevice,
});
return (
<div>
<select onChange={(e) => setInputDevice(e.target.value)}>
{audioInputDevices.map(device => (
<option key={device.deviceId} value={device.deviceId}>
{device.label}
</option>
))}
</select>
<select onChange={(e) => setOutputDevice(e.target.value)}>
{audioOutputDevices.map(device => (
<option key={device.deviceId} value={device.deviceId}>
{device.label}
</option>
))}
</select>
<button onClick={callStatus === 'idle' ? startCall : endCall}>
{callStatus === 'idle' ? 'Start Call' : 'End Call'}
</button>
</div>
);
}
The DialNexaProvider Component
For applications where multiple components need access to call state, wrap your app with DialNexaProvider and use the useDialNexaContext hook:
// App.tsx
import { DialNexaProvider } from '@dialnexa/react';
function App() {
return (
<DialNexaProvider
agentId="your-agent-id"
publicKey="your-public-key"
>
<CallButton />
<TranscriptDisplay />
<CallStatus />
</DialNexaProvider>
);
}
// CallButton.tsx
import { useDialNexaContext } from '@dialnexa/react';
function CallButton() {
const { startCall, callStatus } = useDialNexaContext();
return (
<button onClick={startCall} disabled={callStatus !== 'idle'}>
Call
</button>
);
}
TypeScript Types
Full type definitions are included in the package. Key types:
type CallStatus = 'idle' | 'connecting' | 'connected' | 'ended' | 'error';
type CallEndReason = 'user_hangup' | 'agent_hangup' | 'max_duration' | 'error' | 'network_error';
interface TranscriptTurn {
speaker: 'agent' | 'user';
text: string;
timestamp: number; // milliseconds since call start
confidence?: number; // for user turns, transcription confidence (0-1)
}
interface DialNexaError {
code: string; // e.g., 'MICROPHONE_PERMISSION_DENIED', 'CONNECTION_FAILED'
message: string;
}
Browser Compatibility
The SDK uses WebRTC for audio transport. WebRTC is supported in:
- Chrome 74+
- Firefox 78+
- Safari 14.1+ (iOS 14.5+ on mobile)
- Edge 79+
Internet Explorer is not supported. Older mobile browsers may have WebRTC limitations.
Microphone permission: The SDK requests microphone access when startCall() is called. The browser shows a permission prompt if not already granted. Handle the MICROPHONE_PERMISSION_DENIED error code if the user denies access.
HTTPS Requirement
WebRTC and microphone access require HTTPS. The SDK will not work on HTTP origins (except localhost for development). Ensure your production deployment uses HTTPS.
Related Pages