Survey Integration Recipe
Complete patterns for integrating Sibilance voice surveys into your application.
Overview
This recipe covers common patterns for integrating Sibilance surveys, handling results, and providing a great user experience.
Basic Integration
React Component
tsx
import { useSibilance, FloatingMicButton } from '@sibilance.is/client/react';
function SurveyIntegration() {
const { voiceState, surveyState, toggleSession } = useSibilance({
surveyKey: process.env.NEXT_PUBLIC_SIBILANCE_SURVEY_KEY!,
}, {
onComplete: async (yaml) => {
// Submit results to your backend
await fetch('/api/survey-results', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ results: yaml })
});
}
});
return (
<div>
<FloatingMicButton
isConnected={voiceState.isConnected}
onClick={toggleSession}
/>
{surveyState.isActive && (
<div className="survey-status">
Survey in progress...
</div>
)}
</div>
);
}Vanilla JavaScript
javascript
import { SibilanceClient } from '@sibilance.is/client';
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here',
}, {
onComplete: async (yaml) => {
await fetch('/api/survey-results', {
method: 'POST',
body: JSON.stringify({ results: yaml })
});
}
});
// Start survey
document.getElementById('start-survey').addEventListener('click', async () => {
await client.connect();
});Result Handling
Submit to Backend
typescript
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here'
}, {
onComplete: async (yaml) => {
try {
const response = await fetch('/api/survey-results', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
surveyId: 'your-survey-id',
results: yaml,
timestamp: new Date().toISOString()
})
});
if (!response.ok) {
throw new Error('Failed to submit results');
}
const data = await response.json();
console.log('Results submitted:', data);
} catch (error) {
console.error('Error submitting results:', error);
// Retry logic or show error to user
}
}
});Process Results Locally
typescript
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here'
}, {
onComplete: (yaml) => {
// Process results
const processed = yaml.map(item => ({
field: item.field,
value: item.value,
step: item.sourceStep,
timestamp: item.timestamp
}));
// Store locally
localStorage.setItem('survey-results', JSON.stringify(processed));
// Update UI
displayResults(processed);
}
});Error Handling
Comprehensive Error Handling
typescript
const client = new SibilanceClient({
surveyKey: 'sibilance_your_key_here'
}, {
onComplete: async (yaml) => {
// Handle completion
},
onError: (error) => {
console.error('Survey error:', error);
// Show user-friendly error
if (error.message.includes('microphone')) {
showNotification('Please allow microphone access');
} else if (error.message.includes('survey')) {
showNotification('Survey not found. Please check your Survey Key.');
} else {
showNotification('An error occurred. Please try again.');
}
}
});
// Handle connection errors
try {
await client.connect();
} catch (error) {
console.error('Failed to connect:', error);
handleConnectionError(error);
}Progress Tracking
Show Survey Progress
tsx
function SurveyProgress() {
const { surveyState } = useSibilance({
surveyKey: 'sibilance_your_key_here'
});
return (
<div className="survey-progress">
<h3>Survey Progress</h3>
{surveyState.isActive && (
<>
<p>Current step: {surveyState.currentStepId}</p>
<p>Collected: {surveyState.collectedInfo.length} items</p>
<div className="progress-bar">
<div
className="progress-fill"
style={{
width: `${(surveyState.collectedInfo.length / 10) * 100}%`
}}
/>
</div>
</>
)}
{surveyState.isComplete && (
<div className="complete">
✅ Survey completed!
</div>
)}
</div>
);
}Conditional Rendering
Show Survey Only When Needed
tsx
function ConditionalSurvey() {
const [showSurvey, setShowSurvey] = useState(false);
const { voiceState, toggleSession } = useSibilance({
surveyKey: 'sibilance_your_key_here',
autoStart: false
});
if (!showSurvey) {
return (
<button onClick={() => setShowSurvey(true)}>
Start Survey
</button>
);
}
return (
<div>
<button onClick={() => setShowSurvey(false)}>
Close Survey
</button>
<FloatingMicButton
isConnected={voiceState.isConnected}
onClick={toggleSession}
/>
</div>
);
}Related
- Survey Results - Handling survey results
- Survey Customization - Customizing surveys
- React Integration - React patterns