> 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/convai-pixel-streaming-embed/react-typescript.md).

# 在 React TypeScript 应用中嵌入体验

在 React TypeScript 应用中安装 Pixel Streaming Embed 包，渲染已发布的体验，并通过你自己的界面进行控制。

在用 TypeScript 编写的 React 应用中渲染已发布的 Convai Pixel Streaming 体验，并通过你自己的代码控制其摄像头、音频、麦克风和聊天。最后，用户点击开始后，体验会在你的页面中运行。

### 先决条件

* 一个使用 TypeScript 编写的 React 18 应用，并配有 Vite 之类的打包工具。
* 已发布体验的体验 ID，以及一种授权方式：一个返回 Convai 认证令牌的服务器路由，或一个已被 Convai 加入允许名单的域名。参见 [发布并授权体验](/api-docs/zh/cha-jian-yu-ji-cheng/convai-pixel-streaming-embed/whitelisting-and-publishing-an-experience.md).

### 安装包

当前版本是 <code class="expression">space.vars.experience\_embed\_version</code>.

{% tabs %}
{% tab title="npm" %}

```bash
npm install @convai/experience-embed
```

{% endtab %}

{% tab title="pnpm" %}

```bash
pnpm add @convai/experience-embed
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add @convai/experience-embed
```

{% endtab %}
{% endtabs %}

### 渲染体验

`PixelStreamComponent` 会为该体验请求一个会话，并将其渲染在一个 iframe 中。它会填满其父元素，所以请为父元素设置大小。此示例会先从你服务器上的一个路由获取认证令牌， `/api/convai-token`，然后再渲染该组件：

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

```tsx
import { useEffect, useRef, useState } from 'react';
import {
  PixelStreamComponent,
  type PixelStreamComponentHandles,
} from '@convai/experience-embed';

export default function App() {
  const streamRef = useRef<PixelStreamComponentHandles>(null);
  const [token, setToken] = useState<string>();

  useEffect(() => {
    fetch('/api/convai-token')
      .then((response) => response.json())
      .then((body: { token: string }) => setToken(body.token));
  }, []);

  if (!token) return <p>加载中…</p>;

  return (
    <div style={{ width: '100%', height: '100vh' }}>
      <PixelStreamComponent
        ref={streamRef}
        expId="YOUR_EXPERIENCE_ID"
        authToken={token}
        onIframeLoaded={() => console.log('体验已加载')}
      />
    </div>
  );
}
```

{% endcode %}

如果 Convai 已将你的域名加入允许名单，则省略 `authToken` 并直接渲染该组件。

{% hint style="warning" %}
在渲染组件之前先获取令牌，并在整个会话期间保留它。新的 `authToken`, `expId`，或 `endUserId` 值会请求一个新会话并重新加载体验。
{% endhint %}

### 开始体验

组件首先会显示一个 **点击开始你的体验** 屏幕，并在用户点击后启动体验。若要显示你自己的屏幕，请将其作为 `InitialScreen`传入。自定义屏幕不会自行启动体验，因此请从其中调用 `initializeExperience()` ：

```tsx
<PixelStreamComponent
  ref={streamRef}
  expId="YOUR_EXPERIENCE_ID"
  authToken={token}
  InitialScreen={
    <button onClick={() => streamRef.current?.initializeExperience()}>
      开始导览
    </button>
  }
  LoadingScreenComponent={<p>正在准备体验…</p>}
/>
```

`LoadingScreenComponent` 会覆盖 iframe，直到流页面报告已完成加载。

### 控制体验

在 `onIframeLoaded` 触发后再调用 ref 上的方法。在那之前调用的方法不会发送任何内容：

```tsx
await streamRef.current?.enableCamera();
streamRef.current?.disableCharacterAudio();
streamRef.current?.sendMessageToCharacter('火灾出口在哪里？');
streamRef.current?.muteMicrophone();
streamRef.current?.setChatStyle({ backgroundOpacity: 0.3 });
```

若要跟踪体验内部发生的情况，请传入诸如 `onCharacterMessage` 和 `onMicStatus` 之类的回调作为 props。 [Pixel Streaming Embed API 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-pixel-streaming-embed/api-reference.md) 列出了所有方法、回调和负载。

### 验证嵌入

加载页面并点击开始屏幕。

{% hint style="success" %}
体验会替换开始屏幕，浏览器控制台会记录 `体验已加载`.
{% endhint %}

### 故障排查

#### 嵌入内容要求你联系 Convai

**症状：** 嵌入内容显示 `请联系 convai 以将 <origin> 加入白名单！` ，而不是开始屏幕。

**原因：** 嵌入内容没有 `authToken`，并且页面域名不在你账户的允许名单中，或者体验 ID 错误。

**修复：** 传入认证令牌，或请 Convai 将该域名加入允许名单。检查体验 ID。

**验证：** 重新加载页面。开始屏幕会出现。

#### 嵌入内容报告认证令牌无效

**症状：** 嵌入内容显示 `此体验无法启动：Convai 认证令牌无效或已过期。`

**原因：** Convai 拒绝了传入的令牌，作为 `authToken`.

**修复：** 在你的服务器上铸造一个新令牌，然后用它再次渲染该组件。

**验证：** 重新加载页面。开始屏幕会出现。

#### 点击自定义开始屏幕后没有任何作用

**症状：** 页面显示你的 `InitialScreen`，但点击它不会启动体验。

**原因：** 一个自定义 `InitialScreen` 会替换默认屏幕及其点击处理程序。

**修复：** 调用 `initializeExperience()` 你屏幕上的 ref。

**验证：** 点击你的屏幕后会显示体验。

### 后续步骤

{% content-ref url="/pages/87b57936662c69d8802f20f500191b181163cf02" %}
[Pixel Streaming Embed API 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-pixel-streaming-embed/api-reference.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/convai-pixel-streaming-embed/react-typescript.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.
