DialstackComponentsProvider
The provider makes the DialStack instance and client secret available to all child components.
Usage
import { initialize } from '@dialstack/sdk-js';
import { DialstackComponentsProvider } from '@dialstack/sdk-react';
const dialstack = initialize({
publishableKey: 'pk_live_YOUR_KEY',
});
function App() {
return (
<DialstackComponentsProvider dialstack={dialstack} clientSecret="cs_live_...">
<YourApp />
</DialstackComponentsProvider>
);
}
Props
| Prop | Type | Required | Description |
|---|---|---|---|
dialstack | DialStackInstance | Yes | Instance from initialize() |
clientSecret | string | ClientSecretResponse | Yes | Session token from your backend |
children | ReactNode | Yes | Child components |
clientSecret
The clientSecret prop accepts either a string or the full session response object:
// String only - you handle refresh
<DialstackComponentsProvider
dialstack={dialstack}
clientSecret="cs_live_abc123..."
>
// Full response - SDK handles refresh automatically
<DialstackComponentsProvider
dialstack={dialstack}
clientSecret={{
client_secret: "cs_live_abc123...",
expires_at: "2025-01-15T12:00:00Z"
}}
>
useDialstackComponents Hook
Access the provider context in child components:
import { useDialstackComponents } from '@dialstack/sdk-react';
function StatusIndicator() {
const { dialstack, clientSecret } = useDialstackComponents();
return <div>{clientSecret ? 'Connected' : 'Not connected'}</div>;
}
Return Value
interface UseDialstackComponentsReturn {
dialstack: DialStackInstance;
clientSecret: string | ClientSecretResponse;
}
Error: Missing Provider
If you use a component outside the provider, you'll see this error:
Error: Could not find DialStack context; You need to wrap your app
in a <DialstackComponentsProvider> provider.
See https://docs.dialstack.ai/sdks/react for setup instructions.
Fix: Wrap your component tree with the provider:
// Before (error)
function App() {
return <CallLogs />;
}
// After (working)
function App() {
return (
<DialstackComponentsProvider dialstack={dialstack} clientSecret={secret}>
<CallLogs />
</DialstackComponentsProvider>
);
}
Multiple Providers
You can use multiple providers for different accounts:
function MultiAccountDashboard() {
return (
<div>
<DialstackComponentsProvider dialstack={dialstack} clientSecret={accountASecret}>
<h2>Account A</h2>
<CallLogs />
</DialstackComponentsProvider>
<DialstackComponentsProvider dialstack={dialstack} clientSecret={accountBSecret}>
<h2>Account B</h2>
<CallLogs />
</DialstackComponentsProvider>
</div>
);
}
Complete Example
import { useState, useEffect } from 'react';
import { initialize } from '@dialstack/sdk-js';
import { DialstackComponentsProvider } from '@dialstack/sdk-react';
import { CallLogs } from '@dialstack/sdk-react/call-logs';
import { Voicemails } from '@dialstack/sdk-react/voicemails';
const dialstack = initialize({
publishableKey: 'pk_live_YOUR_KEY',
appearance: {
theme: 'auto',
variables: {
colorPrimary: '#6772E5',
},
},
});
interface Session {
client_secret: string;
expires_at: string;
}
function App() {
const [session, setSession] = useState<Session | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
async function fetchSession() {
try {
const response = await fetch('/api/dialstack/session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ accountId: 'acct_123' }),
});
if (!response.ok) {
throw new Error('Failed to create session');
}
const data = await response.json();
setSession(data);
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error');
}
}
fetchSession();
}, []);
if (error) {
return <div>Error: {error}</div>;
}
if (!session) {
return <div>Loading...</div>;
}
return (
<DialstackComponentsProvider dialstack={dialstack} clientSecret={session}>
<div className="dashboard">
<h1>Voice Dashboard</h1>
<CallLogs />
<Voicemails userId="user_123" />
</div>
</DialstackComponentsProvider>
);
}
export default App;
Handling API errors
Calls made through the instance reject with an ApiError, which carries the HTTP status and, when the API returns one, a machine-readable code. Use isApiError to narrow an unknown error:
import { isApiError } from '@dialstack/sdk-js';
try {
await dialstack.phoneNumbers.list({ limit: 20 });
} catch (err) {
if (isApiError(err)) {
if (err.status === 401) {
// Session expired — mint a new client secret
}
console.error(err.status, err.code, err.message);
} else {
throw err;
}
}
Prefer isApiError(err) over err instanceof ApiError. The error is created inside @dialstack/sdk-js but caught in your code, and instanceof compares against one specific class, so it can return false even for a genuine API error — for example when the error crosses an iframe or worker boundary, or when more than one copy of the package ends up installed. isApiError checks the error's own fields instead, so it holds in those cases. The ApiError class is still exported if you need it for other purposes.
Next Steps
- CallHistory - Compact call history for a phone number
- CallLogs - Call history table with pagination
- Softphone - Embedded WebRTC phone
- Voicemails - Voicemail component
- Authentication - Session management