Next.JS

Découvrez comment créer une application web permettant des conversations vocales avec des agents IA ElevenLabs

Ce tutoriel vous guidera dans la création d’un client web capable d’interagir avec un agent ElevenLabs. Vous apprendrez à mettre en œuvre des conversations vocales en temps réel, permettant aux utilisateurs de parler à un agent IA capable d’écouter, de comprendre et de répondre naturellement grâce à la synthèse vocale.

Prérequis

  1. Un agent ElevenLabs créé en suivant ce guide
  2. npm installé sur votre système local.
  3. Nous utiliserons Typescript dans ce tutoriel, mais vous pouvez utiliser Javascript si vous le préférez.

Vous cherchez un exemple complet ? Consultez notre démo Next.js sur GitHub.

Configuration

1

Créer un projet Next.js

Ouvrez une fenêtre de terminal et exécutez la commande suivante :

npm create next-app my-conversational-agent

Elle vous posera quelques questions sur la façon de créer votre projet. Pour ce tutoriel, nous suivrons les suggestions par défaut.

2

Accéder au répertoire du projet

cd my-conversational-agent
3

Installer la dépendance ElevenLabs

npm install @elevenlabs/react
4

Tester la configuration

Exécutez la commande suivante pour démarrer le serveur de développement et ouvrir l’URL fournie dans votre navigateur :

npm run dev

Mettre en œuvre les agents ElevenLabs

1

Créer le composant de conversation

Créez un fichier 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

Mettre à jour la page principale

Remplacez le contenu de app/page.tsx par :

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>
);
}

Cette étape d’authentification est requise uniquement pour les agents privés. Si vous utilisez un agent public, vous pouvez ignorer cette section et utiliser directement agentId dans l’appel startSession.

Si vous utilisez un agent privé qui exige une authentification, vous devrez générer une URL signée depuis votre serveur. Cette section explique comment procéder.

Prérequis

  1. Un compte ElevenLabs et une clé API. Inscrivez-vous ici.
1

Créer des variables d’environnement

Créez un fichier .env.local à la racine de votre projet :

.env.local
ELEVENLABS_API_KEY=your-api-key-here
NEXT_PUBLIC_AGENT_ID=your-agent-id-here
  1. Veillez à ajouter .env.local à votre fichier .gitignore afin d’éviter de valider accidentellement des identifiants sensibles dans votre gestionnaire de versions.
  2. N’exposez jamais votre clé API dans le code côté client. Conservez-la toujours de manière sécurisée sur le serveur.
2

Créer une route API

Créez un fichier 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

Mettre à jour le composant Conversation

Modifiez votre fichier conversation.tsx pour récupérer et utiliser l’URL signée :

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 ...
}

Les URL signées expirent après une courte période. Toutefois, les conversations lancées avant leur expiration se poursuivent sans interruption. En environnement de production, mettez en œuvre une gestion appropriée des erreurs et une logique de renouvellement des URL pour démarrer de nouvelles conversations.

Étapes suivantes

Vous disposez désormais d’une implémentation de base. Vous pouvez :

  1. Ajouter un retour visuel sur l’activité vocale
  2. Mettre en œuvre une logique de gestion des erreurs et de nouvelle tentative
  3. Ajouter l’affichage de l’historique des conversations
  4. Personnaliser l’interface pour l’adapter à votre marque

Pour des fonctionnalités et des options de personnalisation plus avancées, consultez le package @elevenlabs/react.