import { useConversation } from '@elevenlabs/react'; import { z } from 'zod'; import { useState } from 'react'; export default function VoiceAgent() { const [transcript, setTranscript] = useState>([]); const [error, setError] = useState(null); const { startConversation, stopConversation, status, isSpeaking } = useConversation({ // Agent Configuration agentId: process.env.NEXT_PUBLIC_ELEVENLABS_AGENT_ID!, // Authentication (choose one) // Option 1: API key (for private agents, less secure) // apiKey: process.env.NEXT_PUBLIC_ELEVENLABS_API_KEY, // Option 2: Signed URL (most secure, recommended for production) signedUrl: async () => { const response = await fetch('/api/elevenlabs/auth'); const { signedUrl } = await response.json(); return signedUrl; }, // Client-side tools (browser functions) clientTools: { updateCart: { description: "Update the shopping cart with items", parameters: z.object({ item: z.string().describe("The item name"), quantity: z.number().describe("Quantity to add"), action: z.enum(['add', 'remove']).describe("Add or remove item") }), handler: async ({ item, quantity, action }) => { console.log(`${action} ${quantity}x ${item}`); // Your cart logic here return { success: true, total: 99.99 }; } }, navigate: { description: "Navigate to a different page", parameters: z.object({ url: z.string().url().describe("The URL to navigate to") }), handler: async ({ url }) => { window.location.href = url; return { success: true }; } } }, // Event handlers onConnect: () => { console.log('Connected to agent'); setTranscript([]); setError(null); }, onDisconnect: () => { console.log('Disconnected from agent'); }, onEvent: (event) => { switch (event.type) { case 'transcript': setTranscript(prev => [ ...prev, { role: 'user', text: event.data.text } ]); break; case 'agent_response': setTranscript(prev => [ ...prev, { role: 'agent', text: event.data.text } ]); break; case 'tool_call': console.log('Tool called:', event.data.tool_name, event.data.parameters); break; case 'error': console.error('Agent error:', event.data); setError(event.data.message); break; } }, onError: (error) => { console.error('Connection error:', error); setError(error.message); }, // Regional compliance (for GDPR) serverLocation: 'us' // 'us' | 'global' | 'eu-residency' | 'in-residency' }); return (

Voice Agent

{/* Controls */}
{/* Status */}

Status: {status}

{isSpeaking &&

Agent is speaking...

}
{/* Error */} {error && (
Error: {error}
)} {/* Transcript */}

Transcript

{transcript.length === 0 ? (

No conversation yet. Click "Start Conversation" to begin.

) : ( transcript.map((message, i) => (

{message.role === 'user' ? 'You' : 'Agent'}

{message.text}

)) )}
); }