Next.JS

Aprende a crear una aplicación web que permita mantener conversaciones de voz con agentes de IA de ElevenLabs

Este tutorial te guiará para crear un cliente web que pueda interactuar con un agente de ElevenLabs. Aprenderás a implementar conversaciones de voz en tiempo real, para que usuarios puedan hablar con un agente de IA capaz de escuchar, comprender y responder de forma natural mediante síntesis de voz.

Lo que necesitas

  1. Un agente de ElevenLabs creado siguiendo esta guía
  2. npm instalado en tu sistema local.
  3. En este tutorial usaremos Typescript, pero puedes usar Javascript si lo prefieres.

¿Buscas un ejemplo completo? Consulta nuestra demo de Next.js en GitHub.

Configuración

1

Crea un nuevo proyecto de Next.js

Abre una ventana de terminal y ejecuta el siguiente comando:

npm create next-app my-conversational-agent

Te hará algunas preguntas sobre cómo crear tu proyecto. En este tutorial seguiremos las sugerencias predeterminadas.

2

Ve al directorio del proyecto

cd my-conversational-agent
3

Instala la dependencia de ElevenLabs

npm install @elevenlabs/react
4

Prueba la configuración

Ejecuta el siguiente comando para iniciar el servidor de desarrollo y abre la URL proporcionada en tu navegador:

npm run dev

Implementa ElevenLabs Agents

1

Crea el componente de conversación

Crea un archivo nuevo: app/components/conversation.tsx:

app/components/conversation.tsx
'use client';
import { useConversation } from '@elevenlabs/react';
import { useCallback } from 'react';
export function Conversation() {
const conversation = useConversation({
onConnect: () => console.log('Connected'),
onDisconnect: () => console.log('Disconnected'),
onMessage: (message) => console.log('Message:', message),
onError: (error) => console.error('Error:', error),
});
const startConversation = useCallback(async () => {
try {
// Request microphone permission
await navigator.mediaDevices.getUserMedia({ audio: true });
// Start the conversation with your agent
await conversation.startSession({
agentId: 'YOUR_AGENT_ID', // Replace with your agent ID
userId: 'YOUR_CUSTOMER_USER_ID', // Optional field for tracking your end user IDs
});
} catch (error) {
console.error('Failed to start conversation:', error);
}
}, [conversation]);
const stopConversation = useCallback(async () => {
await conversation.endSession();
}, [conversation]);
return (
<div className="flex flex-col items-center gap-4">
<div className="flex gap-2">
<button
onClick={startConversation}
disabled={conversation.status === 'connected'}
className="px-4 py-2 bg-blue-500 text-white rounded disabled:bg-gray-300"
>
Start Conversation
</button>
<button
onClick={stopConversation}
disabled={conversation.status !== 'connected'}
className="px-4 py-2 bg-red-500 text-white rounded disabled:bg-gray-300"
>
Stop Conversation
</button>
</div>
<div className="flex flex-col items-center">
<p>Status: {conversation.status}</p>
<p>Agent is {conversation.isSpeaking ? 'speaking' : 'listening'}</p>
</div>
</div>
);
}
2

Actualiza la página principal

Sustituye el contenido de app/page.tsx por lo siguiente:

app/page.tsx
'use client';
import { ConversationProvider } from '@elevenlabs/react';
import { Conversation } from './components/conversation';
export default function Home() {
return (
<ConversationProvider>
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm">
<h1 className="text-4xl font-bold mb-8 text-center">
ElevenLabs Agents
</h1>
<Conversation />
</div>
</main>
</ConversationProvider>
);
}

Este paso de autenticación solo es necesario para agentes privados. Si usas un agente público, puedes omitir esta sección y usar directamente el agentId en la llamada a startSession.

Si usas un agente privado que requiere autenticación, tendrás que generar una URL firmada desde tu servidor. Esta sección explica cómo configurarlo.

Lo que necesitas

  1. Una cuenta y una clave de API de ElevenLabs. Regístrate aquí.
1

Crea variables de entorno

Crea un archivo .env.local en la raíz de tu proyecto:

.env.local
ELEVENLABS_API_KEY=your-api-key-here
NEXT_PUBLIC_AGENT_ID=your-agent-id-here
  1. Asegúrate de añadir .env.local a tu archivo .gitignore para evitar confirmar accidentalmente credenciales sensibles en el control de versiones.
  2. Nunca expongas tu clave de API en el código del lado cliente. Mantenla siempre segura en el servidor.
2

Crea una ruta de API

Crea un archivo nuevo: app/api/get-signed-url/route.ts:

app/api/get-signed-url/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
try {
const response = await fetch(
`https://api.elevenlabs.io/v1/convai/conversation/get-signed-url?agent_id=${process.env.NEXT_PUBLIC_AGENT_ID}`,
{
headers: {
'xi-api-key': process.env.ELEVENLABS_API_KEY!,
},
}
);
if (!response.ok) {
throw new Error('Failed to get signed URL');
}
const data = await response.json();
return NextResponse.json({ signedUrl: data.signed_url });
} catch (error) {
return NextResponse.json(
{ error: 'Failed to generate signed URL' },
{ status: 500 }
);
}
}
3

Actualiza el componente Conversation

Modifica tu conversation.tsx para obtener y usar la URL firmada:

app/components/conversation.tsx
// ... existing imports ...
export function Conversation() {
// ... existing conversation setup ...
const getSignedUrl = async (): Promise<string> => {
const response = await fetch("/api/get-signed-url");
if (!response.ok) {
throw new Error(`Failed to get signed url: ${response.statusText}`);
}
const { signedUrl } = await response.json();
return signedUrl;
};
const startConversation = useCallback(async () => {
try {
// Request microphone permission
await navigator.mediaDevices.getUserMedia({ audio: true });
const signedUrl = await getSignedUrl();
// Start the conversation with your signed url
await conversation.startSession({
signedUrl,
});
} catch (error) {
console.error('Failed to start conversation:', error);
}
}, [conversation]);
// ... rest of the component ...
}

Las URL firmadas caducan al poco tiempo. Sin embargo, cualquier conversación iniciada antes de que caduquen continuará sin interrupciones. En un entorno de producción, implementa una gestión de errores adecuada y lógica de actualización de URL para iniciar nuevas conversaciones.

Próximos pasos

Ahora que tienes una implementación básica, puedes:

  1. Añadir indicaciones visuales de actividad de voz
  2. Implementar gestión de errores y lógica de reintentos
  3. Añadir una vista del historial de chat
  4. Personalizar la interfaz para que se adapte a tu marca

Para ver funciones más avanzadas y opciones de personalización, consulta el paquete @elevenlabs/react.