Overview
TheuseTamboVoice hook provides browser-based audio recording with automatic transcription via the Tambo API. It handles microphone access, audio capture, and speech-to-text conversion.
How It Works
- User clicks a button to start recording
- Browser requests microphone access
- Audio is captured as WebM format
- When recording stops, audio is automatically sent to Tambo’s transcription API
- Transcript is returned and can be used as chat input
import { useTamboVoice, useTamboThreadInput } from '@tambo-ai/react';
import { Mic, MicOff } from 'lucide-react';
function VoiceInput() {
const {
startRecording,
stopRecording,
isRecording,
isTranscribing,
transcript,
transcriptionError,
mediaAccessError,
} = useTamboVoice();
const { setValue, submit } = useTamboThreadInput();
const handleToggleRecording = () => {
if (isRecording) {
stopRecording();
} else {
startRecording();
}
};
// Auto-fill input when transcript is ready
useEffect(() => {
if (transcript) {
setValue(transcript);
}
}, [transcript, setValue]);
return (
<div>
<button
onClick={handleToggleRecording}
disabled={isTranscribing}
className="p-2 rounded-full hover:bg-gray-100"
>
{isRecording ? <MicOff className="w-5 h-5 text-red-500" /> : <Mic className="w-5 h-5" />}
</button>
{mediaAccessError && (
<div className="text-red-500 text-sm mt-2">
Microphone access denied: {mediaAccessError}
</div>
)}
{transcriptionError && (
<div className="text-red-500 text-sm mt-2">
Transcription failed: {transcriptionError}
</div>
)}
{isTranscribing && (
<div className="text-gray-500 text-sm mt-2">
Transcribing...
</div>
)}
</div>
);
}
import { useEffect } from 'react';
import { useTamboVoice, useTamboThreadInput } from '@tambo-ai/react';
function VoiceInput() {
const { transcript } = useTamboVoice();
const { setValue, submit } = useTamboThreadInput();
useEffect(() => {
if (transcript) {
setValue(transcript);
submit(); // Auto-submit after transcription
}
}, [transcript, setValue, submit]);
// ... rest of component
}
Return Values
Recording Controls
Transcription State
Error Handling
Advanced Examples
Recording with Visual Feedback
components/voice-button.tsx
Inline Chat Input with Voice
components/chat-input.tsx
Recording Duration Display
Error Handling
Microphone Access Errors
Transcription Errors
Best Practices
Provide clear visual feedback
Provide clear visual feedback
Show recording state prominently:
- Use red color for recording
- Add pulsing animation
- Display recording duration
- Show transcribing spinner
Handle permissions gracefully
Handle permissions gracefully
Microphone access requires user permission:
- Explain why you need access
- Provide clear error messages
- Offer a retry button
- Fall back to text input
Disable conflicting actions
Disable conflicting actions
Prevent issues during recording:
Reset state between recordings
Reset state between recordings
The hook automatically resets state when starting a new recording. You don’t need to manually clear the transcript.
Consider mobile devices
Consider mobile devices
- Test on iOS Safari and Android Chrome
- Ensure tap targets are large enough (min 44x44px)
- Handle screen rotation
- Consider battery usage for long recordings
Browser Support
Voice input requires:- MediaRecorder API (audio recording)
- Microphone access permission
- WebM audio support
- Chrome 49+
- Firefox 25+
- Safari 14.1+
- Edge 79+
Troubleshooting
Microphone access denied
Microphone access denied
- Check browser permissions (chrome://settings/content/microphone)
- Ensure HTTPS is used (required for secure contexts)
- Try different browser
- On mobile, check system permissions
No audio captured
No audio captured
- Verify microphone is working in other apps
- Check microphone is selected in browser settings
- Ensure no other app is using the microphone
- Try restarting the browser
Transcription returning empty
Transcription returning empty
- Ensure audio is audible (check recording level)
- Speak clearly and avoid background noise
- Check network connection
- Verify API key is valid
Recording stops immediately
Recording stops immediately
- Check for JavaScript errors in console
- Verify stopRecording isn’t called accidentally
- Ensure component isn’t unmounting
Next Steps
Suggestions
Add AI-powered prompt suggestions
Thread Input Hook
Handle text input and submission
Message Images
Add image attachments
Error Handling
Handle errors properly