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

In deze tutorial leer je hoe je een webclient maakt die kan communiceren met een ElevenLabs-agent. Je leert realtime spraakgesprekken implementeren, zodat gebruikers kunnen praten met een AI-agent die kan luisteren, begrijpen en op natuurlijke wijze kan reageren met spraaksynthese.

> **Note**
>
> Wil je bouwen met React/Next.js? Bekijk onze [Next.js handleiding](/docs/nl/eleven-agents/guides/quickstarts/next-js)

## Wat je nodig hebt

1. Een ElevenLabs-agent die je volgens [deze handleiding](/docs/nl/eleven-agents/quickstart) hebt gemaakt
2. `npm` geïnstalleerd op je lokale systeem
3. Basiskennis van JavaScript

## Project instellen

#### Maak een projectmap

Open een terminal en maak een nieuwe map voor je project:

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

#### Initialiseer npm en installeer dependencies

Initialiseer een nieuw npm-project en installeer de vereiste pakketten:

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

#### Stel de basisprojectstructuur in

Voeg dit toe aan je `package.json`:

**`package.json`**

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

Maak de volgende bestandsstructuur:

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

## De voicechatinterface implementeren

#### Maak de HTML-interface

Stel in `index.html` een eenvoudige gebruikersinterface in:

![](/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>
```

#### Implementeer de gesprekslogica

Implementeer de functionaliteit in `script.js`:

**`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);
```

#### Start de frontendserver

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

> **Note**
>
> Vervang `'YOUR_AGENT_ID'` door je daadwerkelijke agent-ID van ElevenLabs.

#### (Optioneel) Authenticeren met een Signed URL

> **Note**
>
> Deze authenticatiestap is alleen vereist voor privéagents. Als je een openbare agent gebruikt, kun je dit gedeelte overslaan en de `agentId` rechtstreeks gebruiken in de aanroep van `startSession`.

#### Maak omgevingsvariabelen

Maak een `.env`-bestand in de hoofdmap van je project:

**`.env`**

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

> **Warning**
>
> Voeg `.env` toe aan je `.gitignore`-bestand om te voorkomen dat je per ongeluk gevoelige credentials commit.

#### Stel de backend in

1. Installeer aanvullende dependencies:

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

2. Maak een nieuwe map met de naam `backend`:

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

#### Maak de server

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

#### Werk de clientcode bij

Pas je `script.js` aan om de Signed URL op te halen en te gebruiken:

**`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**
>
> Signed URL's verlopen na korte tijd. Gesprekken die vóór het verlopen zijn gestart, gaan echter zonder onderbreking door. Implementeer in een productieomgeving goede foutafhandeling en logica om URL's te vernieuwen voor het starten van nieuwe gesprekken.

#### Werk package.json bij

**`package.json`**

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

#### Start de applicatie

Start de applicatie met:

```bash
npm run dev
```

## Volgende stappen

Nu je een basisimplementatie hebt, kun je:

1. Visuele feedback voor spraakactiviteit toevoegen
2. Foutafhandeling en logica voor opnieuw proberen implementeren
3. Een chatgeschiedenisweergave toevoegen
4. De UI aanpassen aan je merk

> **Info**
>
> Bekijk voor geavanceerdere functies en aanpassingsopties het pakket
> [@elevenlabs/client](https://www.npmjs.com/package/@elevenlabs/client).