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

# React SDK

> **Info**
>
> ElevenAgentsの仕組みについては、[ElevenAgentsの概要](/docs/ja/eleven-agents/overview)を参照してください。

## インストール

パッケージマネージャーを使用して、プロジェクトにパッケージをインストールします。

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

> **Tip**
>
> 以前のバージョンからアップグレードしますか？`npx skills add elevenlabs/packages`を実行すると、
> AIコーディングエージェント向けの`elevenlabs:sdk-migration`スキルがインストールされ、importの変更、
> `ConversationProvider`のラップ、APIの更新が自動化されます。

> **Note**
>
> `@elevenlabs/react`は`@elevenlabs/client`のすべてを再エクスポートするため、
> 両方のパッケージをインストールする必要はありません。

## 使用方法

エージェントに接続し、ユーザーが音声会話を開始・終了できる最小限の動作例を以下に示します：

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

以下のセクションで、各部分を詳しく説明します。

### ConversationProvider

すべての会話フックは`ConversationProvider`内で使用する必要があります。このプロバイダーでアプリ（または対象のサブツリー）をラップしてください。

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

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

#### プロバイダーのprops

プロバイダーは、コールバック、クライアントツール、オーバーライド、サーバーロケーションを含む`useConversation`と同じオプションを受け取ります。そのため、各フックの利用側ではなくプロバイダーレベルで設定できます。

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

##### 制御されたミュート状態

プロバイダーは、制御されたミュート状態の管理用に`isMuted`と`onMutedChange` propsをサポートしています。これにより、ミュート状態を外部で永続化できます（例：セッション間）。

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

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

### useConversation

すべての粒度の細かいフックを単一の戻り値にまとめた便利なReactフックです。親要素に`ConversationProvider`が必要です。

> **Note**
>
> レンダリングパフォーマンスを向上させるには、代わりに[粒度の細かいフック](#granular-hooks)の使用を検討してください。
> `useConversation`は状態が変わるたびに再レンダリングを実行しますが、粒度の細かいフックは
> それぞれが対象とする状態の一部が変化した場合にのみ再レンダリングします。

#### 会話を初期化する

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

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

ElevenAgentsでは、音声会話にマイクへのアクセスが必要です。会話が始まる前に、アプリのUIで理由を説明し、アクセスを許可できるようにしてください。

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

#### オプション

フックはオプション付きで初期化できます。これらは`ConversationProvider`レベルでも渡せます。

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

オプションは次のとおりです：

* **clientTools** - エージェントが呼び出せるクライアントツールのオブジェクト定義。詳細は[以下](#client-tools)を参照してください。
* **overrides** - 会話設定のオーバーライド用オブジェクト定義。詳細は[以下](#conversation-overrides)を参照してください。
* **textOnly** - 会話をテキストのみモードで実行するかどうか。詳細は[以下](#text-only)を参照してください。
* **serverLocation** - サーバーロケーションを指定します（`"us"`、`"eu-residency"`、`"in-residency"`、`"global"`）。デフォルトは`"us"`です。

#### コールバックの概要

* **onConnect** - 会話接続が確立されたときに呼び出されるハンドラー。
* **onDisconnect** - 会話接続が終了したときに呼び出されるハンドラー。
* **onMessage** - 新しいメッセージを受信したときに呼び出されるハンドラー。ユーザー音声の暫定または確定の文字起こし、LLMが生成した応答、デバッグオプションが有効な場合のデバッグメッセージが含まれます。
* **onError** - エラーが発生したときに呼び出されるハンドラー。
* **onAudio** - オーディオデータを受信したときに呼び出されるハンドラー。
* **onModeChange** - 会話モード（話す／聞く）が変わったときに呼び出されるハンドラー。
* **onStatusChange** - 接続ステータスが変わったときに呼び出されるハンドラー。
* **onCanSendFeedbackChange** - フィードバックを送信できるかどうかが変わったときに呼び出されるハンドラー。
* **onDebug** - デバッグ情報が利用可能になったときに呼び出されるハンドラー。
* **onUnhandledClientToolCall** - 未処理のクライアントツール呼び出しが発生したときに呼び出されるハンドラー。
* **onVadScore** - 音声アクティビティ検出スコアが変わったときに呼び出されるハンドラー。
* **onAudioAlignment** - オーディオアラインメントデータを受信したときに呼び出されるハンドラー。エージェント音声の文字単位のタイミング情報を提供します。
* **onAgentChatResponsePart** - エージェントの応答テキストが生成される際に、start、delta、stopイベントとして呼び出されるハンドラー。テキストのみモードでは常に送信されます。音声会話では、エージェントの`client_events`設定で`agent_chat_response_part`を有効にしてください。

##### クライアントツール

クライアントツールを使うと、エージェントがクライアント側の機能を呼び出せます。モーダルを開く、ユーザーに代わってAPI呼び出しを行うなど、クライアントでのアクションをトリガーできます。

クライアントツールの定義は関数のオブジェクトで、[ElevenLabs UI](https://elevenlabs.io/app/agents)内の設定と一致している必要があります。UIでは、さまざまなツールに名前と説明を付け、エージェントから渡されるパラメーターを設定できます。

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

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

関数が値を返す場合、その値は応答としてエージェントに返されます。

エージェントが応答を待機して反応できるよう、ElevenLabs UIでツールが会話をブロックするよう明示的に設定する必要があります。そうしない場合、エージェントは成功したものとみなし、会話を続行します。

> **Note**
>
> よりReactらしい方法でクライアントツールを登録するには、
> [useConversationClientTool](#useconversationclienttool)を参照してください。

##### 会話のオーバーライド

会話のさまざまな設定をオーバーライドし、他のユーザー操作に基づいて動的に設定できます。

さまざまな設定をオーバーライドできます。これらの設定は任意で、会話体験のカスタマイズに使用できます。

利用可能な設定は次のとおりです：

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

##### テキストのみ

エージェントがテキストのみモード、つまりオーディオメッセージを送受信しないように設定されている場合、このフラグを使用して軽量版の会話を利用できます。この場合、ユーザーにマイクの権限を求めることはなく、オーディオコンテキストも作成されません。

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

##### 制御された状態

フックオプションを通じて、会話状態の特定の要素を直接制御できます：

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

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

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

##### データレジデンシー

接続するElevenLabsサーバーリージョンを指定できます。詳細は[データレジデンシーガイド](/docs/ja/overview/administration/data-residency)を参照してください。

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

#### メソッド

##### startSession

`startSession`メソッドは接続を確立し、マイクを使用してElevenLabs Agentsエージェントとの通信を開始します。このメソッドはオプションオブジェクトを受け取り、`signedUrl`、`conversationToken`、`agentId`のいずれかが必須です。

エージェントIDは[ElevenLabs UI](https://elevenlabs.io/app/agents)で取得できます。

会話をユーザーに紐付けるため、独自のエンドユーザーIDも渡すことをおすすめします。

> **Note**
>
> 接続タイプは会話モードに応じて自動的に推論されます。音声会話では
> WebRTCが、テキストのみの会話ではデフォルトでWebSocketが使用されます。必要に応じて、
> `connectionType`を明示的に指定することもできます。

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

パブリックエージェント（認証が有効になっていないエージェント）の場合、必要なのは`agentId`のみです。

会話に認可が必要な場合は、REST APIを使用して、WebSocket接続用の署名付きリンクまたはWebRTC接続用の会話トークンを生成してください。

`startSession`は、`conversationId`に解決されるPromiseを返します。この値は、個別の会話を識別するために使用できるグローバルに一意な会話IDです。

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

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

会話を手動で終了するためのメソッドです。接続を切断して会話を終了します。

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

##### setVolume

会話の出力音量を設定します。0から1までの`volume`フィールドを持つオブジェクトを受け取ります。

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

##### sendUserMessage

エージェントにテキストメッセージを送信します。

マイクを使用する代わりに、ユーザーがメッセージを入力できるようにするために使用できます。`sendContextualUpdate`とは異なり、これはユーザーメッセージとして扱われ、エージェントに会話の応答を促します。

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

応答をトリガーしないコンテキスト情報をエージェントに送信します。

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

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

##### sendFeedback

会話の品質に関するフィードバックを提供します。これはエージェントのパフォーマンス向上に役立ちます。

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

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

##### sendUserActivity

中断を防ぐため、ユーザーのアクティビティをエージェントに通知します。ユーザーがアプリを操作中で、エージェントが発話を一時停止すべき場合、たとえばユーザーがチャットで入力している場合に便利です。

このシグナルを受信した後、エージェントは約2秒間発話を停止します。

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

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

##### changeInputDevice

アクティブな音声会話中にオーディオ入力デバイスを切り替えます。このメソッドは音声会話でのみ使用できます。

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

##### changeOutputDevice

アクティブな音声会話中にオーディオ出力デバイスを切り替えます。このメソッドは音声会話でのみ使用できます。

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

> **Note**
>
> デバイスの切り替えは音声会話でのみ機能します。特定の`deviceId`が指定されていない場合、
> ブラウザーはデフォルトのデバイス選択を使用します。利用可能なデバイスは
> [MediaDevices.enumerateDevices()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices)
> APIで列挙できます。

##### getId

現在の会話IDを返します。

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

##### getInputVolume / getOutputVolume

現在の入出力音量レベル（0～1のスケール）を返すメソッドです。

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

##### getInputByteFrequencyData / getOutputByteFrequencyData

現在の入出力周波数データを含む`Uint8Array`を返すメソッドです。詳細は[AnalyserNode.getByteFrequencyData](https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData)を参照してください。

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

> **Note**
>
> これらのメソッドは音声会話でのみ使用できます。WebRTCモードではオーディオに`pcm_48000`が
> ハードコードされているため、返されたデータを使用するビジュアライゼーションでは、WebSocket接続とは
> 異なるパターンが表示される場合があります。

##### sendMCPToolApprovalResult

MCP（Model Context Protocol）ツール呼び出しの承認結果を送信します。

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

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

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

#### 戻り値

上記のメソッドに加えて、`useConversation`は以下のリアクティブな状態を返します：

* **status** - 現在の接続ステータス（`"disconnected"`、`"connecting"`、`"connected"`）。
* **isSpeaking** - エージェントが現在話しているかどうか。
* **isListening** - エージェントが現在聞いているかどうか。
* **mode** - 現在の会話モード（`"speaking"`または`"listening"`）。
* **isMuted** - マイクが現在ミュートされているかどうか。
* **setMuted** - マイクをミュート／ミュート解除する関数。
* **canSendFeedback** - 現在の会話にフィードバックを送信できるかどうか。
* **message** - 会話からの最新メッセージ。

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

---

## 粒度の細かいフック

レンダリングパフォーマンスを向上させるには、`useConversation`の代わりにこれらのフックを使用してください。各フックは対象とする状態の一部のみを購読するため、コンポーネントは消費するデータが変化した場合にのみ再レンダリングされます。

すべての粒度の細かいフックには、親要素に`ConversationProvider`が必要です。

### useConversationControls

会話を制御するアクションメソッドを返します。安定した関数参照のみを提供するため、このフックによって再レンダリングが発生することはありません。

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

現在の接続ステータスと任意のステータスメッセージを返します。

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

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

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

### useConversationInput

ミュート状態と、マイクのオン／オフを切り替えるセッターを返します。

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

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

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

### useConversationMode

エージェントの発話／聞き取り状態を返します。

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

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

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

### useConversationFeedback

フィードバックの可否と、フィードバックを送信するメソッドを返します。

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

生の会話インスタンスを返します。これは、基盤となる`VoiceConversation`または`TextConversation`オブジェクトに直接アクセスする必要がある高度なユースケース向けのエスケープハッチです。

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

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

---

## useConversationClientTool

Reactコンポーネントからクライアントツールを動的に登録するためのフックです。コンポーネントがアンマウントされると、ツールは自動的に登録解除されます。

プロバイダーレベルでは利用できないコンポーネントのstateやpropsに、ツールのハンドラーからアクセスする必要がある場合に便利です。

```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} />;
}
```

このフックは常にハンドラーの最新のクロージャ値を使用するため、古いstateを心配する必要はありません。