> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Vite (JavaScript)

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, afin que les utilisateurs puissent parler avec un agent IA capable d’écouter, de comprendre et de répondre naturellement grâce à la synthèse vocale.

> **Note**
>
> Vous souhaitez développer avec React/Next.js ? Consultez notre [guide Next.js](/docs/fr/eleven-agents/guides/quickstarts/next-js)

## Prérequis

1. Un agent ElevenLabs créé en suivant [ce guide](/docs/fr/eleven-agents/quickstart)
2. `npm` installé sur votre système local
3. Des connaissances de base en JavaScript

## Configuration du projet

#### Créez un répertoire de projet

Ouvrez un terminal et créez un nouveau répertoire pour votre projet :

```bash
mkdir elevenlabs-conversational-ai
cd elevenlabs-conversational-ai
```

#### Initialisez npm et installez les dépendances

Initialisez un nouveau projet npm et installez les paquets requis :

```bash
npm init -y
npm install vite @elevenlabs/client
```

#### Configurez la structure de base du projet

Ajoutez ceci à votre `package.json` :

**`package.json`**

```json package.json {4}
{
    "scripts": {
        ...
        "dev:frontend": "vite"
    }
}
```

Créez la structure de fichiers suivante :

```shell {2,3}
elevenlabs-conversational-ai/
├── index.html
├── script.js
├── package-lock.json
├── package.json
└── node_modules
```

## Mise en œuvre de l’interface de chat vocal

#### Créez l’interface HTML

Dans `index.html`, configurez une interface utilisateur simple :

![](/docs/_fern-img/5ad9dea65eddc50beaf444e5d319dc5094df0f4183e50f7ed01900394b3ff9d2.webp)

**`index.html`**

```html index.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>ElevenLabs Agents</title>
    </head>
    <body style="font-family: Arial, sans-serif; text-align: center; padding: 50px;">
        <h1>ElevenLabs Agents</h1>
        <div style="margin-bottom: 20px;">
            <button id="startButton" style="padding: 10px 20px; margin: 5px;">Start Conversation</button>
            <button id="stopButton" style="padding: 10px 20px; margin: 5px;" disabled>Stop Conversation</button>
        </div>
        <div style="font-size: 18px;">
            <p>Status: <span id="connectionStatus">Disconnected</span></p>
            <p>Agent is <span id="agentStatus">listening</span></p>
        </div>
        <script type="module" src="../images/script.js"></script>
    </body>
</html>
```

#### Mettez en œuvre la logique de conversation

Dans `script.js`, mettez en œuvre la fonctionnalité :

**`script.js`**

```javascript script.js
import { Conversation } from '@elevenlabs/client';

const startButton = document.getElementById('startButton');
const stopButton = document.getElementById('stopButton');
const connectionStatus = document.getElementById('connectionStatus');
const agentStatus = document.getElementById('agentStatus');

let conversation;

async function startConversation() {
    try {
        // Request microphone permission
        await navigator.mediaDevices.getUserMedia({ audio: true });

        // Start the conversation
        conversation = await Conversation.startSession({
            agentId: 'YOUR_AGENT_ID', // Replace with your agent ID
            onConnect: () => {
                connectionStatus.textContent = 'Connected';
                startButton.disabled = true;
                stopButton.disabled = false;
            },
            onDisconnect: () => {
                connectionStatus.textContent = 'Disconnected';
                startButton.disabled = false;
                stopButton.disabled = true;
            },
            onError: (error) => {
                console.error('Error:', error);
            },
            onModeChange: (mode) => {
                agentStatus.textContent = mode.mode === 'speaking' ? 'speaking' : 'listening';
            },
        });
    } catch (error) {
        console.error('Failed to start conversation:', error);
    }
}

async function stopConversation() {
    if (conversation) {
        await conversation.endSession();
        conversation = null;
    }
}

startButton.addEventListener('click', startConversation);
stopButton.addEventListener('click', stopConversation);
```

#### Démarrez le serveur frontend

```shell
npm run dev:frontend
```

> **Note**
>
> Veillez à remplacer `'YOUR_AGENT_ID'` par l’ID réel de votre agent ElevenLabs.

#### (Facultatif) Authentifiez-vous avec une URL signée

> **Note**
>
> 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`.

#### Créez des variables d’environnement

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

**`.env`**

```env .env
ELEVENLABS_API_KEY=your-api-key-here
AGENT_ID=your-agent-id-here
```

> **Warning**
>
> Veillez à ajouter `.env` à votre fichier `.gitignore` pour éviter de valider accidentellement des identifiants sensibles.

#### Configurez le backend

1. Installez les dépendances supplémentaires :

```bash
npm install express cors dotenv
```

2. Créez un dossier nommé `backend` :

```shell {2}
elevenlabs-conversational-ai/
├── backend
...
```

#### Créez le serveur

**`backend/server.js`**

```javascript backend/server.js
require("dotenv").config();

const express = require("express");
const cors = require("cors");

const app = express();
app.use(cors());
app.use(express.json());

const PORT = process.env.PORT || 3001;

app.get("/api/get-signed-url", async (req, res) => {
    try {
        const response = await fetch(
            `https://api.elevenlabs.io/v1/convai/conversation/get-signed-url?agent_id=${process.env.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();
        res.json({ signedUrl: data.signed_url });
    } catch (error) {
        console.error("Error:", error);
        res.status(500).json({ error: "Failed to generate signed URL" });
    }
});

app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});
```

#### Mettez à jour le code client

Modifiez votre `script.js` pour récupérer et utiliser l’URL signée :

**`script.js`**

```javascript script.js {2-10,16,19,20}
// ... existing imports and variables ...

async function getSignedUrl() {
    const response = await fetch('http://localhost:3001/api/get-signed-url');
    if (!response.ok) {
        throw new Error(`Failed to get signed url: ${response.statusText}`);
    }
    const { signedUrl } = await response.json();
    return signedUrl;
}

async function startConversation() {
    try {
        await navigator.mediaDevices.getUserMedia({ audio: true });

        const signedUrl = await getSignedUrl();

        conversation = await Conversation.startSession({
            signedUrl,
            // agentId has been removed...
            onConnect: () => {
                connectionStatus.textContent = 'Connected';
                startButton.disabled = true;
                stopButton.disabled = false;
            },
            onDisconnect: () => {
                connectionStatus.textContent = 'Disconnected';
                startButton.disabled = false;
                stopButton.disabled = true;
            },
            onError: (error) => {
                console.error('Error:', error);
            },
            onModeChange: (mode) => {
                agentStatus.textContent = mode.mode === 'speaking' ? 'speaking' : 'listening';
            },
        });
    } catch (error) {
        console.error('Failed to start conversation:', error);
    }
}

// ... rest of the code ...
```

> **Warning**
>
> Les URL signées expirent après une courte période. Toutefois, les conversations commencé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.

#### Mettez à jour le package.json

**`package.json`**

```json package.json {4,5}
{
    "scripts": {
        ...
        "dev:backend": "node backend/server.js",
        "dev": "npm run dev:frontend & npm run dev:backend"
    }
}
```

#### Exécutez l’application

Démarrez l’application avec :

```bash
npm run dev
```

## Prochaines étapes

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

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

> **Info**
>
> Pour des fonctionnalités et options de personnalisation plus avancées, consultez le paquet
> [@elevenlabs/client](https://www.npmjs.com/package/@elevenlabs/client).