# React

对于 React 项目，GitBook 提供了预构建组件，使嵌入文档变得简单且符合惯用方式。这些组件会自动处理状态管理、上下文和生命周期。

## 步骤

{% stepper %}
{% step %}

#### 安装包

添加 `@gitbook/embed` 到你的 React 项目中：

```bash
npm install @gitbook/embed
```

如需完整的 API 参考和源代码，请查看 [`@gitbook/embed` GitHub 上的包](https://github.com/GitbookIO/gitbook/tree/main/packages/embed).
{% endstep %}

{% step %}

#### 导入 React 组件

导入 `GitBookProvider` 和 `GitBookFrame` 组件：

```jsx
import {
  GitBookProvider,
  GitBookFrame,
} from "@gitbook/embed/react";
```

{% endstep %}

{% step %}

#### 用 GitBookProvider 包裹你的应用

在组件树的根部或你需要嵌入的地方添加 provider：

```jsx
function App() {
  return (
    <GitBookProvider siteURL="https://docs.company.com">
      <YourAppContent />
    </GitBookProvider>
  );
}
```

{% endstep %}

{% step %}

#### 添加 GitBookFrame 组件

将 frame 组件放在你希望嵌入出现的位置：

```jsx
function App() {
  return (
    <GitBookProvider siteURL="https://docs.company.com">
      <div className="app">
        <YourAppContent />
        <GitBookFrame
          visitor={{
            token: 'your-jwt-token', // 可选：用于自适应内容或已认证访问
            unsignedClaims: { userId: '123' } // 可选：用于动态表达式的自定义声明
          }}
        />
      </div>
    </GitBookProvider>
  );
}
```

{% endstep %}

{% step %}

#### 自定义嵌入

将配置属性传递给 frame 组件：

```jsx
<GitBookProvider siteURL="https://docs.company.com">
  <GitBookFrame
    trademark={false}
    tabs={['assistant', 'search', 'docs']}
    colorScheme="dark"
    greeting={{ title: '欢迎！', subtitle: '我能帮你什么？' }}
    suggestions={['什么是 GitBook？', '我该如何开始？']}
    actions={[
      {
        icon: 'circle-question',
        label: '联系支持',
        onClick: () => window.open('https://support.example.com', '_blank')
      }
    ]}
    tools={[/* ... */]}
    visitor={{
      token: 'your-jwt-token',
      unsignedClaims: { userId: '123' }
    }}
  />
</GitBookProvider>
```

如果你省略 `colorScheme`，嵌入会遵循 iframe 的 CSS `color-scheme`。这样它就能自动匹配你的应用主题。
{% endstep %}

{% step %}

#### 使用 useGitBook hook 控制嵌入

使用 `useGitBook` hook 以编程方式与嵌入交互：

```jsx
import { useGitBook } from "@gitbook/embed/react";

function HelpButton() {
  const gitbook = useGitBook();
  const frameURL = gitbook.getFrameURL({ visitor: { token: '...' } });
  
  const handleNavigate = () => {
    const iframe = document.createElement('iframe');
    iframe.src = frameURL;
    const frame = gitbook.createFrame(iframe);
    frame.navigateToPage('/getting-started');
    frame.navigateToAssistant();
    frame.postUserMessage('How do I get started?');
  };

  return <button onClick={handleNavigate}>获取帮助</button>;
}
```

{% endstep %}

{% step %}

#### 按条件渲染嵌入

仅在需要时显示嵌入：

```jsx
function App() {
  const [showEmbed, setShowEmbed] = useState(false);

  return (
    <GitBookProvider siteURL="https://docs.company.com">
      <button onClick={() => setShowEmbed(true)}>获取帮助</button>
      {showEmbed && <GitBookFrame />}
    </GitBookProvider>
  );
}
```

{% endstep %}

{% step %}

#### 在 Next.js 或服务端渲染中使用

动态导入组件以避免 SSR 问题：

```jsx
import dynamic from "next/dynamic";

const GitBookProvider = dynamic(
  () => import("@gitbook/embed/react").then((mod) => mod.GitBookProvider),
  { ssr: false }
);

const GitBookFrame = dynamic(
  () => import("@gitbook/embed/react").then((mod) => mod.GitBookFrame),
  { ssr: false }
);
```

{% endstep %}
{% endstepper %}

## 属性与配置

**GitBookProvider 属性：**

| 属性         | 类型          | 必填 | 默认值 | 描述                                                   |
| ---------- | ----------- | -- | --- | ---------------------------------------------------- |
| `siteURL`  | `string`    | 是  | 不适用 | 你的 GitBook 文档站点 URL（例如， `https://docs.company.com`). |
| `children` | `ReactNode` | 是  | 不适用 | 在 provider 内渲染的子组件。                                  |

**GitBookFrame 属性：**

所有配置选项都可以作为属性传递给 `<GitBookFrame>`。可用选项请参见下方的配置部分。

| 属性            | 类型                  | 必填 | 默认值                    | 描述                    |
| ------------- | ------------------- | -- | ---------------------- | --------------------- |
| `className`   | `string`            | 否  | `null`                 | 应用于 frame 容器的 CSS 类名。 |
| `style`       | `object`            | 否  | `{}`                   | 应用于 frame 容器的内联样式。    |
| `colorScheme` | `'light' \| 'dark'` | 否  | 继承自 CSS `color-scheme` | 覆盖嵌入的配色方案。            |
| `visitor`     | `object`            | 否  | `{}`                   | 已认证访问选项（见下文）。         |

**useGitBook Hook：**

返回一个 `GitBookClient` 实例，包含以下方法：

* `getFrameURL(options?: { visitor?: {...}, colorScheme?: 'light' | 'dark' })` → `string` - 获取 iframe URL
* `createFrame(iframe: HTMLIFrameElement)` → `GitBookFrameClient` - 创建 frame 客户端

frame 客户端提供：

* `navigateToPage(path: string)` → `void`
* `navigateToAssistant()` → `void`
* `postUserMessage(message: string)` → `void`
* `clearChat()` → `void`
* `configure(settings: {...})` → `void`
* `on(event: string, listener: Function)` → `() => void`

## 配置选项

配置选项可作为以下对象上的属性使用： `<GitBookFrame>`:

### `tabs`

覆盖显示哪些标签页。

搜索默认启用。如果你设置 `tabs`，嵌入将只显示你列出的标签页。

* **类型**: `('assistant' | 'search' | 'docs')[]`

### `colorScheme`

覆盖嵌入的配色方案。

当省略时，嵌入会遵循 iframe 的 CSS `color-scheme`，从而继承父页面或浏览器偏好。

* **类型**: `'light' | 'dark'`

### `actions`

显示在侧边栏中、与标签页并列的自定义操作按钮。每个操作按钮在点击时都会触发回调。

**注意**：这之前名为 `buttons`。请改用 `actions` 。

* **类型**: `Array<{ icon: string, label: string, onClick: () => void }>`

### `greeting`

在 Assistant 标签页中显示的欢迎消息。

* **类型**: `{ title: string, subtitle: string }`

### `suggestions`

在 Assistant 欢迎屏幕中显示的建议问题。

* **类型**: `string[]`

### `trademark`

在嵌入 UI 中显示或隐藏 GitBook 商标——包括 Docs Embed 页脚和 Assistant 品牌标识。

* **类型**: `boolean`
* **默认值**: `true`

### `tools`

用于扩展 Assistant 的自定义 AI 工具。详情请参见 [创建自定义工具](https://gitbook-v2-lrp5kto0w-gitbook.vercel.app/url/gitbook.com/docs/documentation/zh/docs-site/embedding/configuration/creating-custom-tools) 。

* **类型**: `Array<{ name: string, description: string, inputSchema: object, execute: Function, confirmation?: {...} }>`

### `visitor` （已认证访问）

用于 [自适应内容](https://gitbook-v2-lrp5kto0w-gitbook.vercel.app/url/gitbook.com/docs/documentation/zh/site-access/adaptive-content) 和 [已认证访问](https://gitbook-v2-lrp5kto0w-gitbook.vercel.app/url/gitbook.com/docs/documentation/zh/site-access/authenticated-access).

* **类型**: `{ token?: string, unsignedClaims?: Record<string, unknown> }`

## 常见陷阱

* **未使用 GitBookProvider 包裹** – `GitBookFrame` 需要一个父级 `GitBookProvider` 才能工作。
* **在没有动态导入的情况下与 SSR 一起使用** – 该组件使用浏览器 API，必须在 Next.js 或其他 SSR 框架中动态导入。
* **siteURL 与已发布文档不匹配** – 请确保 `siteURL` 属性与线上文档站点 URL 完全一致。
* **在 provider 外调用 useGitBook** – `useGitBook` hook 必须在作为 `GitBookProvider`.
* **子级的组件内部使用** 树中存在多个 provider `GitBookProvider` – 避免嵌套多个
* **实例，因为这会导致上下文冲突。** 使用旧的组件名称 `GitBookFrame`– 现在组件是 `GitBookAssistantFrame`.
