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

# SDK de React

> **Info**
>
> Consulta la [visión general de ElevenAgents](/docs/es/eleven-agents/overview) para entender cómo
> funciona ElevenAgents.

## Instalación

Instala el paquete en tu proyecto mediante un gestor de paquetes.

```shell
npm install @elevenlabs/react
# or
yarn add @elevenlabs/react
# or
pnpm install @elevenlabs/react
```

> **Tip**
>
> ¿Estás actualizando desde una versión anterior? Ejecuta `npx skills add elevenlabs/packages` para instalar la
> skill `elevenlabs:sdk-migration` para tu agente de programación con IA, que automatiza los cambios de importación,
> la integración de `ConversationProvider` y las actualizaciones de la API.

> **Note**
>
> `@elevenlabs/react` vuelve a exportar todo desde `@elevenlabs/client`, así que no necesitas instalar
> ambos paquetes.

## Uso

Aquí tienes un ejemplo mínimo funcional que se conecta a un agente y permite al usuario iniciar y terminar una conversación de voz:

```tsx
import {
  ConversationProvider,
  useConversationControls,
  useConversationStatus,
} from "@elevenlabs/react";

function App() {
  return (
    <ConversationProvider>
      <Agent />
    </ConversationProvider>
  );
}

function Agent() {
  const { startSession, endSession } = useConversationControls();
  const { status } = useConversationStatus();

  if (status === "connected") {
    return <button onClick={endSession}>End</button>;
  }

  return (
    <button onClick={() => startSession({ agentId: "agent_7101k5zvyjhmfg983brhmhkd98n6" })}>
      Start
    </button>
  );
}
```

Las secciones siguientes explican cada parte en detalle.

### ConversationProvider

Todos los hooks de conversación deben usarse dentro de un `ConversationProvider`. Envuelve tu aplicación (o el subárbol correspondiente) con este proveedor.

```tsx
import { ConversationProvider } from "@elevenlabs/react";

function App() {
  return (
    <ConversationProvider>
      <YourComponents />
    </ConversationProvider>
  );
}
```

#### Props del proveedor

El proveedor acepta las mismas opciones que `useConversation` —incluidos callbacks, herramientas de cliente, anulaciones y ubicación del servidor—, por lo que puedes configurarlas a nivel de proveedor en lugar de hacerlo en cada componente que consume el hook.

```tsx
<ConversationProvider
  onConnect={() => console.log("Connected")}
  onDisconnect={() => console.log("Disconnected")}
  onError={(error) => console.error("Error:", error)}
  clientTools={{
    displayMessage: (parameters: { text: string }) => {
      alert(parameters.text);
      return "Message displayed";
    },
  }}
  serverLocation="eu-residency"
>
  <YourComponents />
</ConversationProvider>
```

##### Estado de silencio controlado

El proveedor admite las props `isMuted` y `onMutedChange` para gestionar el estado de silencio de forma controlada, lo que te permite conservarlo externamente (por ejemplo, entre sesiones).

```tsx
const [muted, setMuted] = useState(false);

<ConversationProvider isMuted={muted} onMutedChange={setMuted}>
  <YourComponents />
</ConversationProvider>;
```

### useConversation

Un práctico hook de React que combina todos los hooks granulares en un único valor de retorno. Requiere un `ConversationProvider` antecesor.

> **Note**
>
> Para mejorar el rendimiento del renderizado, considera usar los [hooks granulares](#granular-hooks).
> `useConversation` provoca un nuevo renderizado ante cualquier cambio de estado, mientras que los hooks granulares solo
> se vuelven a renderizar cuando cambia su parte específica del estado.

#### Inicializar la conversación

```tsx
import { useConversation } from "@elevenlabs/react";

function MyComponent() {
  const conversation = useConversation();
  // ...
}
```

Ten en cuenta que ElevenAgents requiere acceso al micrófono para las conversaciones de voz. Antes de que empiece la conversación, considera explicarlo y permitir el acceso desde la interfaz de tu aplicación.

```js
// call after explaining to the user why the microphone access is needed
await navigator.mediaDevices.getUserMedia({ audio: true });
```

#### Opciones

El hook puede inicializarse opcionalmente con opciones. También puedes pasarlas en el nivel de `ConversationProvider`.

```tsx
const conversation = useConversation({
  /* options object */
});
```

Las opciones incluyen:

* **clientTools**: definición de objeto para herramientas de cliente que el agente puede invocar. Consulta los [detalles a continuación](#client-tools).
* **overrides**: definición de objeto para anulaciones de la configuración de conversación. Consulta los [detalles a continuación](#conversation-overrides).
* **textOnly**: indica si la conversación debe ejecutarse en modo de solo texto. Consulta los [detalles a continuación](#text-only).
* **serverLocation**: especifica la ubicación del servidor (`"us"`, `"eu-residency"`, `"in-residency"`, `"global"`). El valor predeterminado es `"us"`.

#### Resumen de callbacks

* **onConnect**: controlador que se llama cuando se establece la conexión de la conversación.
* **onDisconnect**: controlador que se llama cuando finaliza la conexión de la conversación.
* **onMessage**: controlador que se llama cuando se recibe un mensaje nuevo. Pueden ser transcripciones provisionales o finales de la voz del usuario, respuestas generadas por el LLM o mensajes de depuración cuando hay una opción de depuración activada.
* **onError**: controlador que se llama cuando se produce un error.
* **onAudio**: controlador que se llama cuando se reciben datos de audio.
* **onModeChange**: controlador que se llama cuando cambia el modo de conversación (hablando/escuchando).
* **onStatusChange**: controlador que se llama cuando cambia el estado de la conexión.
* **onCanSendFeedbackChange**: controlador que se llama cuando cambia la posibilidad de enviar comentarios.
* **onDebug**: controlador que se llama cuando hay información de depuración disponible.
* **onUnhandledClientToolCall**: controlador que se llama cuando se encuentra una llamada a una herramienta de cliente sin gestionar.
* **onVadScore**: controlador que se llama cuando cambia la puntuación de detección de actividad de voz.
* **onAudioAlignment**: controlador que se llama cuando se reciben datos de alineación de audio, que proporcionan información de tiempos a nivel de carácter para el habla del agente.
* **onAgentChatResponsePart**: controlador que se llama con el texto de respuesta del agente a medida que se genera, mediante eventos de inicio, delta y finalización. Se envía siempre en modo de solo texto; para conversaciones de voz, activa `agent_chat_response_part` en la configuración de `client_events` del agente.

##### Herramientas de cliente

Las herramientas de cliente permiten que el agente invoque funcionalidades del lado del cliente. Puedes utilizarlas para activar acciones en el cliente, como abrir un modal o realizar una llamada a la API en nombre del usuario.

La definición de herramientas de cliente es un objeto de funciones y debe ser idéntica a tu configuración en la [interfaz de ElevenLabs](https://elevenlabs.io/app/agents), donde puedes nombrar y describir distintas herramientas, así como configurar los parámetros que pasa el agente.

```ts
const conversation = useConversation({
  clientTools: {
    displayMessage: (parameters: { text: string }) => {
      alert(parameters.text);

      return "Message displayed";
    },
  },
});
```

Si la función devuelve un valor, se le pasa al agente como respuesta.

La herramienta debe configurarse explícitamente para bloquear la conversación en la interfaz de ElevenLabs para que el agente espere la respuesta y reaccione a ella. De lo contrario, el agente asumirá que ha tenido éxito y continuará la conversación.

> **Note**
>
> Para un enfoque más idiomático de React para registrar herramientas de cliente, consulta
> [useConversationClientTool](#useconversationclienttool).

##### Anulaciones de conversación

Puedes optar por anular distintos ajustes de la conversación y establecerlos dinámicamente según otras interacciones del usuario.

Admitimos la anulación de distintos ajustes. Son opcionales y pueden usarse para personalizar la experiencia de conversación.

Están disponibles los siguientes ajustes:

```ts
const conversation = useConversation({
  overrides: {
    agent: {
      prompt: {
        prompt: "My custom prompt",
      },
      firstMessage: "My custom first message",
      language: "en",
    },
    tts: {
      voiceId: "custom voice id",
    },
    conversation: {
      textOnly: true,
    },
  },
});
```

##### Solo texto

Si tu agente está configurado para ejecutarse en modo de solo texto, es decir, no envía ni recibe mensajes de audio, puedes usar esta marca para utilizar una versión más ligera de la conversación. En ese caso, no se le pedirá permiso al usuario para usar el micrófono ni se creará ningún contexto de audio.

```ts
const conversation = useConversation({
  textOnly: true,
});
```

##### Estado controlado

Puedes controlar determinados aspectos del estado de la conversación directamente mediante las opciones del hook:

```ts
const [micMuted, setMicMuted] = useState(false);

const conversation = useConversation({
  micMuted,
  // ... other options
});

// Update controlled state
setMicMuted(true); // This will automatically mute the microphone
```

##### Residencia de datos

Puedes especificar a qué región de servidor de ElevenLabs conectarte. Para obtener más información, consulta la [guía de residencia de datos](/docs/es/overview/administration/data-residency).

```ts
const conversation = useConversation({
  serverLocation: "eu-residency", // or "us", "in-residency", "global"
});
```

#### Métodos

##### startSession

El método `startSession` establece la conexión y empieza a usar el micrófono para comunicarse con el agente de ElevenLabs Agents. El método acepta un objeto de opciones, en el que se requiere `signedUrl`, `conversationToken` o `agentId`.

Puedes obtener el ID del agente desde la [interfaz de ElevenLabs](https://elevenlabs.io/app/agents).

También recomendamos pasar tus propios ID de usuarios finales para asociar las conversaciones a tus usuarios.

> **Note**
>
> El tipo de conexión se infiere automáticamente según el modo de conversación. Las conversaciones de voz
> usan WebRTC y las conversaciones de solo texto usan WebSocket de forma predeterminada. Aun así, puedes especificar
> explícitamente `connectionType` si lo necesitas.

```js
const conversation = useConversation();

// For public agents, pass in the agent ID
const conversationId = await conversation.startSession({
  agentId: "agent_7101k5zvyjhmfg983brhmhkd98n6",
  userId: "user_9302xkm82nds93", // optional field
});
```

Para los agentes públicos (es decir, agentes que no tienen la autenticación activada), solo se requiere `agentId`.

Si la conversación requiere autorización, usa la API REST para generar enlaces firmados para una conexión WebSocket o un token de conversación para una conexión WebRTC.

`startSession` devuelve una promesa que se resuelve en un `conversationId`. El valor es un ID de conversación único globalmente que puedes usar para identificar conversaciones independientes.

#### Conexión WebSocket

```js maxLines=0
// Node.js server

app.get("/signed-url", yourAuthMiddleware, async (req, res) => {
  const response = await fetch(
    `https://api.elevenlabs.io/v1/convai/conversation/get-signed-url?agent_id=${process.env.AGENT_ID}`,
    {
      headers: {
        // Requesting a signed url requires your ElevenLabs API key
        // Do NOT expose your API key to the client!
        "xi-api-key": process.env.ELEVENLABS_API_KEY,
      },
    }
  );

  if (!response.ok) {
    return res.status(500).send("Failed to get signed URL");
  }

  const body = await response.json();
  res.send(body.signed_url);
});
```

```js
// Client

const response = await fetch("/signed-url", yourAuthHeaders);
const signedUrl = await response.text();

await conversation.startSession({
  signedUrl,
});
```

#### Conexión WebRTC

```js maxLines=0
// Node.js server

app.get("/conversation-token", yourAuthMiddleware, async (req, res) => {
  const response = await fetch(
    `https://api.elevenlabs.io/v1/convai/conversation/token?agent_id=${process.env.AGENT_ID}`,
    {
      headers: {
        // Requesting a conversation token requires your ElevenLabs API key
        // Do NOT expose your API key to the client!
        "xi-api-key": process.env.ELEVENLABS_API_KEY,
      }
    }
  );

  if (!response.ok) {
    return res.status(500).send("Failed to get conversation token");
  }

  const body = await response.json();
  res.send(body.token);
});
```

```js
// Client

const response = await fetch("/conversation-token", yourAuthHeaders);
const conversationToken = await response.text();

await conversation.startSession({
  conversationToken,
});
```

##### endSession

Un método para terminar manualmente la conversación. El método desconectará y finalizará la conversación.

```js
await conversation.endSession();
```

##### setVolume

Establece el volumen de salida de la conversación. Acepta un objeto con un campo `volume` entre 0 y 1.

```js
await conversation.setVolume({ volume: 0.5 });
```

##### sendUserMessage

Envía un mensaje de texto al agente.

Puedes usarlo para que el usuario escriba el mensaje en lugar de usar el micrófono. A diferencia de `sendContextualUpdate`, se tratará como un mensaje del usuario e indicará al agente que tome su turno en la conversación.

```js
const { sendUserMessage, sendUserActivity } = useConversation();
const [value, setValue] = useState("");

return (
  <>
    <input
      value={value}
      onChange={e => {
        setValue(e.target.value);
        sendUserActivity();
      }}
    />
    <button
      onClick={() => {
        sendUserMessage(value);
        setValue("");
      }}
    >
      SEND
    </button>
  </>
);
```

##### sendContextualUpdate

Envía información contextual al agente que no activará una respuesta.

```js
const { sendContextualUpdate } = useConversation();

sendContextualUpdate(
  "User navigated to another page. Consider it for next response, but don't react to this contextual update."
);
```

##### sendFeedback

Proporciona comentarios sobre la calidad de la conversación. Esto ayuda a mejorar el rendimiento del agente.

```js
const { sendFeedback } = useConversation();

sendFeedback(true); // positive feedback
sendFeedback(false); // negative feedback
```

##### sendUserActivity

Notifica al agente la actividad del usuario para evitar interrupciones. Es útil cuando el usuario está usando activamente la aplicación y el agente debe dejar de hablar, por ejemplo, cuando el usuario está escribiendo en un chat.

El agente dejará de hablar durante unos 2 segundos después de recibir esta señal.

```js
const { sendUserActivity } = useConversation();

// Call this when user is typing to prevent interruption
sendUserActivity();
```

##### changeInputDevice

Cambia el dispositivo de entrada de audio durante una conversación de voz activa. Este método solo está disponible para conversaciones de voz.

```js
// Change to a specific input device
conversation.changeInputDevice({
  sampleRate: 16000,
  format: "pcm",
  preferHeadphonesForIosDevices: true,
  inputDeviceId: "a1b2c3d4e5f6", // Optional: specific device ID
});
```

##### changeOutputDevice

Cambia el dispositivo de salida de audio durante una conversación de voz activa. Este método solo está disponible para conversaciones de voz.

```js
// Change to a specific output device
conversation.changeOutputDevice({
  sampleRate: 16000,
  format: "pcm",
  outputDeviceId: "a1b2c3d4e5f6", // Optional: specific device ID
});
```

> **Note**
>
> El cambio de dispositivo solo funciona en conversaciones de voz. Si no se proporciona un `deviceId` específico, el
> navegador usará su selección de dispositivo predeterminada. Puedes enumerar los dispositivos disponibles mediante la
> API [MediaDevices.enumerateDevices()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices).

##### getId

Devuelve el ID de la conversación actual.

```js
const { getId } = useConversation();
const conversationId = getId();
console.log(conversationId); // e.g., "conv_9001k1zph3fkeh5s8xg9z90swaqa"
```

##### getInputVolume / getOutputVolume

Métodos que devuelven los niveles de volumen de entrada/salida actuales (escala de 0 a 1).

```js
const { getInputVolume, getOutputVolume } = useConversation();
const inputLevel = getInputVolume();
const outputLevel = getOutputVolume();
```

##### getInputByteFrequencyData / getOutputByteFrequencyData

Métodos que devuelven `Uint8Array`s con los datos de frecuencia de entrada/salida actuales. Consulta [AnalyserNode.getByteFrequencyData](https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData) para obtener más información.

```js
const { getInputByteFrequencyData, getOutputByteFrequencyData } = useConversation();
const inputFrequencyData = getInputByteFrequencyData();
const outputFrequencyData = getOutputByteFrequencyData();
```

> **Note**
>
> Estos métodos solo están disponibles para conversaciones de voz. En modo WebRTC, el audio está codificado para
> usar `pcm_48000`, lo que significa que cualquier visualización que use los datos devueltos podría mostrar patrones diferentes
> a los de las conexiones WebSocket.

##### sendMCPToolApprovalResult

Envía el resultado de aprobación para llamadas a herramientas MCP (Model Context Protocol).

```js
const { sendMCPToolApprovalResult } = useConversation();

// Approve a tool call
sendMCPToolApprovalResult("tc_8k2m4n6p8r0t", true);

// Reject a tool call
sendMCPToolApprovalResult("tc_8k2m4n6p8r0t", false);
```

#### Valores de retorno

Además de los métodos anteriores, `useConversation` devuelve el siguiente estado reactivo:

* **status**: el estado actual de la conexión (`"disconnected"`, `"connecting"`, `"connected"`).
* **isSpeaking**: indica si el agente está hablando actualmente.
* **isListening**: indica si el agente está escuchando actualmente.
* **mode**: el modo de conversación actual (`"speaking"` o `"listening"`).
* **isMuted**: indica si el micrófono está silenciado actualmente.
* **setMuted**: función para silenciar o activar el micrófono.
* **canSendFeedback**: indica si se pueden enviar comentarios para la conversación actual.
* **message**: el mensaje más reciente de la conversación.

```tsx
const { status, isSpeaking, isListening, isMuted, setMuted, canSendFeedback } = useConversation();

return (
  <div>
    <p>Status: {status}</p>
    <p>Agent is {isSpeaking ? 'speaking' : 'listening'}</p>
    <button onClick={() => setMuted(!isMuted)}>
      {isMuted ? 'Unmute' : 'Mute'}
    </button>
  </div>
);
```

---

## Hooks granulares

Para mejorar el rendimiento del renderizado, usa estos hooks en lugar de `useConversation`. Cada hook se suscribe únicamente a su parte específica del estado, de modo que los componentes solo se vuelven a renderizar cuando cambian los datos que consumen.

Todos los hooks granulares requieren un `ConversationProvider` antecesor.

### useConversationControls

Devuelve métodos de acción para controlar la conversación. Este hook no provoca nuevos renderizados, ya que solo proporciona referencias de función estables.

```tsx
import { useConversationControls } from "@elevenlabs/react";

function Controls() {
  const {
    startSession,
    endSession,
    sendUserMessage,
    sendContextualUpdate,
    sendUserActivity,
    setVolume,
    changeInputDevice,
    changeOutputDevice,
    sendMCPToolApprovalResult,
    getId,
    getInputVolume,
    getOutputVolume,
    getInputByteFrequencyData,
    getOutputByteFrequencyData,
  } = useConversationControls();

  return (
    <button onClick={() => startSession({ agentId: "agent_7101k5zvyjhmfg983brhmhkd98n6" })}>
      Start
    </button>
  );
}
```

### useConversationStatus

Devuelve el estado actual de la conexión y un mensaje de estado opcional.

```tsx
import { useConversationStatus } from "@elevenlabs/react";

function StatusIndicator() {
  const { status, message } = useConversationStatus();

  return <p>Status: {status}</p>; // "disconnected" | "connecting" | "connected"
}
```

### useConversationInput

Devuelve el estado de silencio y una función de configuración para activar o desactivar el micrófono.

```tsx
import { useConversationInput } from "@elevenlabs/react";

function MuteToggle() {
  const { isMuted, setMuted } = useConversationInput();

  return <button onClick={() => setMuted(!isMuted)}>{isMuted ? "Unmute" : "Mute"}</button>;
}
```

### useConversationMode

Devuelve el estado de habla/escucha del agente.

```tsx
import { useConversationMode } from "@elevenlabs/react";

function ModeIndicator() {
  const { mode, isSpeaking, isListening } = useConversationMode();

  return <p>Agent is {isSpeaking ? "speaking" : "listening"}</p>;
}
```

### useConversationFeedback

Devuelve la disponibilidad de comentarios y un método para enviarlos.

```tsx
import { useConversationFeedback } from "@elevenlabs/react";

function FeedbackButtons() {
  const { canSendFeedback, sendFeedback } = useConversationFeedback();

  if (!canSendFeedback) return null;

  return (
    <div>
      <button onClick={() => sendFeedback(true)}>Like</button>
      <button onClick={() => sendFeedback(false)}>Dislike</button>
    </div>
  );
}
```

### useRawConversation

Devuelve la instancia de conversación sin procesar. Es una vía de escape para casos de uso avanzados en los que necesitas acceso directo al objeto `VoiceConversation` o `TextConversation` subyacente.

```tsx
import { useRawConversation } from "@elevenlabs/react";

function Advanced() {
  const conversation = useRawConversation();
  // Access the raw conversation instance directly
}
```

---

## useConversationClientTool

Un hook para registrar dinámicamente herramientas de cliente desde componentes de React. Las herramientas se anulan automáticamente al desmontar el componente.

Resulta útil cuando el gestor de una herramienta necesita acceder al estado o las props del componente que no están disponibles en el nivel del proveedor.

```tsx
import { useConversationClientTool } from "@elevenlabs/react";
import { useState } from "react";

function MapComponent() {
  const [location, setLocation] = useState({ lat: 0, lng: 0 });

  useConversationClientTool("getLocation", () => {
    return `${location.lat},${location.lng}`;
  });

  useConversationClientTool("setLocation", (params: { lat: number; lng: number }) => {
    setLocation(params);
    return "Location updated";
  });

  return <Map center={location} />;
}
```

El hook siempre usa el valor de cierre más reciente del gestor, así que no tienes que preocuparte por estados obsoletos.