> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-embody/add-a-chat-widget-to-a-character.md).

# 向角色添加聊天小部件

将 Convai 聊天小部件添加到 Convai Embody 角色中，这样用户就可以通过该角色已建立的连接输入并与它对话。

在 Convai Embody 角色旁边添加 Convai Web SDK 聊天小部件，让用户可以输入文字并与其对话。请在你的 React 应用中角色渲染后使用此页面。最后，从小部件发送的消息会得到语音回复，角色会进行口型同步。

### 前置条件

* 使用……渲染的角色 `ConvaiCharacter` 或 `CharacterModel`。请参阅 [向 React 应用添加一个 3D 角色](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-embody/add-a-3d-character-to-a-react-app.md).

### 将客户端从角色中提取出来

角色持有该连接。 `onReady` 在其身体加载完成且连接已建立后，会将角色交给你，并且 `character.client` 是该连接的 `ConvaiClient`。将其存储在画布外的状态中，因为小部件属于 DOM，无法在 3D 场景内渲染。

### 渲染小部件

`useWidgetClient` 会将角色的客户端适配为 props `ConvaiWidget` 所需并返回 `null` 直到客户端存在。 `ConvaiWidget`, `ConvaiClient`，以及 `useWidgetClient` 都从 `@convai/embody/react`导出，因此应用无需直接从 `@convai/web-sdk`.

{% code title="src/App.tsx" %}

```tsx
import { useState } from 'react'
import {
  ConvaiCharacter,
  ConvaiWidget,
  useWidgetClient,
  type ConvaiClient,
} from '@convai/embody/react'

export default function App({ token }: { token: string }) {
  const [client, setClient] = useState<ConvaiClient | null>(null)
  const widgetClient = useWidgetClient(client)

  return (
    <>
      <ConvaiCharacter
        token={token}
        characterId="YOUR_CHARACTER_ID"
        onReady={(character) => setClient(character.client)}
      />
      {widgetClient && <ConvaiWidget convaiClient={widgetClient} />}
    </>
  )
}
```

{% endcode %}

{% hint style="warning" %}
不要使用 `useConvaiClient`。该钩子会构造第二个 `ConvaiClient`，这会打开第二个连接：小部件会与一个会话通信，而角色会对另一个会话做口型同步，因此角色会保持静默。
{% endhint %}

### 验证小部件

在小部件中输入消息并发送。

{% hint style="success" %}
回复会显示在小部件中，角色会说出它，并且角色的嘴巴会随着音频同步移动。
{% endhint %}

### 下一步

{% content-ref url="/pages/afcae56dd5bee11232aa7e5af42d7608c0a2f044" %}
[React API 参考](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-embody/react-api-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/eb896fafee38ed6296228fce9cc8190b93be03b8" %}
[ConvaiWidget 组件参考](/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/react/convaiwidget.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-embody/add-a-chat-widget-to-a-character.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
