# @demoloop/react 中文文档

规范地址：https://npmcn.com/package/%40demoloop/react/

版本：2\.2\.0
npm 元数据更新时间：2026-11-07T23:34:23.164Z
中文译文更新时间：2026-11-12T04:54:56.064Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40demoloop/react
原文对照：https://npmcn.com/package/%40demoloop/react/?lang=original
项目主页：https://demoloop.ai/
源码仓库：https://github.com/demoloopai/react

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：537 kB，9 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：react \>=18，react-dom \>=18
- 首次发布：2026-06-17T19:58:42.165Z
- 最新版本发布：2026-11-07T23:34:22.979Z
- 近 30 天下载量：2865（2026-10-12 至 2026-11-10，npm 官方下载统计）
- 已发布版本数：32（近 12 个月 32 个）

## 中文简介

嵌入 Demoloop AI 演示的回放组件 .

## 安装

```sh
npm install @demoloop/react
```

也可以使用：`pnpm add @demoloop/react`、`yarn add @demoloop/react`、`bun add @demoloop/react`

## README

# @ demoloop/ 反应

嵌入时的反应组件 [脱摩洛普](https://demoloop.ai/) AI在你的网站上演示.

倒入提供商,浮动CTA,内置按钮,或完整的相遇风格的英雄区段——全部接通同一张起牌,德莫洛普自己的脚本从你的页面上打开.

**🔗 [现场演示 – 反应-demo.demoloop.ai](https://react-demo.demoloop.ai/)** ——一页的每个组件.

## 安装

```bash
npm install @demoloop/react
```

同伴依赖性 : `react >=18`, (中文(简体) ), `react-dom >=18`。 。 。 . **没有其它运行时间解码** ——没有Tailwind,没有帧-动,没有图标库可以安装. 组件将自己的平地CSS和SVG图标装入 `<head>` 一次在第一舱, 并远离你的设计系统的方式.

## 使用量

将您的应用程序( 或任何子树) 包装到 `DemoloopProvider`,然后将任何按钮或部分放入其中.

```tsx
import {
  DemoloopProvider,
  DemoloopFloatingOrb,
  DemoloopButton,
  DemoloopSection,
} from "@demoloop/react";

export default function Layout({ children }) {
  return (
    <DemoloopProvider agentId="agt_xxx">
      {children}
      <DemoloopFloatingOrb />
    </DemoloopProvider>
  );
}
```

就这样——没有CSS导入,没有Tailwind内容-路径配置,没有插件接线.

### 麦克风和你的 `Permissions-Policy`

演示从一个框架运行 `https://app.demoloop.ai`观众会跟它说话 所以这个相框需要麦克风 德莫洛普的脚本和 `DemoloopEmbed` 自行授权`allow="microphone …"` 说到框架 大部分网站不需要别的东西.

如果你的网站发送 `Permissions-Policy` 页眉(或 `<meta http-equiv>`提及 `microphone`,其许可名单必须包括: **你自己的出身和我们的出身**数字 :

```
Permissions-Policy: microphone=(self "https://app.demoloop.ai")
```

`self` 是容易被忽略的部分, 并把它留下 打破演示沉默。 帧只获得一个功能,即它周围的页面也是允许的. 与 `microphone=("https://app.demoloop.ai")`您的页面不允许使用麦克风,所以里面的演示也不允许使用. 然后浏览器拒绝而不显示提示,而演示文稿告诉访问者页面不会让其询问(他们仍然可以在聊天中输入). `microphone=()` 挡住它一样的方式。 无标题 `microphone` 条目是罚款的:默认已允许您的页面, 而 iframe's `allow` 传之.

## 构成部分

### `DemoloopProvider`

持有报价(演示可以运行的地方,以及为何)并曝光 `open()` 编号 : `close()` 给所有的孩子.

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `agentId` | `string` | —— 说 | 探员 每页一个特工 没有,触发器就变了 `open()` 什么也没做. |
| `baseUrl` | `string` | `https://app.demoloop.ai` | 覆为自宿. 尾声 `/d` (0.x要求的)被忽略. |
| `copy` | `DemoloopCopyInput` | 联合国 | SDK 制作的每个字符串, 作为一个打字对象 。 见 [复制](https://npmcn.com/package/%40demoloop/react/#readme-copy)。 。 。 . |
| `theme` | `"light" | "dark"` | `"dark"` | 看看SDK自己的触发器 开始卡跟随你的页面. |
| `lang` | `"en-US" | "es-ES" | string` | —— 说 | 起步卡开通的语言(访客可以在那里更改). 没有它,你的页面 `<html lang>`。 。 。 . |
| `email` | `string` | —— 说 | 当你的应用程序知道谁是访客时 这张卡不要求电子邮件。 未验证,如打字地址为. |
| `name` | `string` | —— 说 | 他们的名字,相传 `email` (而只用它),所以经纪人从来不要. |
| `surfaces` | `("call" | "in-app")[]` | `["call"]` | 演示可以运行的地方,以便提供. 见 [表面和模式](https://npmcn.com/package/%40demoloop/react/#readme-surfaces-and-modes)。 。 。 . |
| `modes` | `("tour" | "help")[]` | `["tour"]` | 演示可能是为了提供它们. |
| `feature` | `string` | —— 说 | 默认焦点特性 id: 巡演被缩小到该特性. |
| `onOpen` | `(info: DemoloopOpenInfo) => void` | —— 说 | 每次触发器打开起动卡时都会拨打. 见 [跟踪](https://npmcn.com/package/%40demoloop/react/#readme-tracking)。 。 。 . |
| `loadScript` | `"mount" | "open"` | `"mount"` | 当取出德摩洛普的脚本. `"open"` 只有在演示开始(或标签中已运行)时才加载,或作为 `DemoloopFloatingOrb` 装上,因为脚本画它。 见 [一个脚本,每个演示](https://npmcn.com/package/%40demoloop/react/#readme-one-script-every-demo)。 。 。 . |

### `DemoloopFloatingOrb`

浮起"AI aura" orb被钉入下角——一个发光的,有形态的梯度环绕着物剂avatar (à la 11Labs). 点击它打开了 Demoloop 的起步卡 .

德莫洛普的脚本绘制出来( D)`window.Demoloop.orb`),在你的页面上,除了起步卡和呼叫之外,在自己的一帧中. 组件本身不起作用;它告诉脚本应该是什么。 框架是一个单独的文档, 所以当您的应用程序有一个对话框或工作表打开时, Orb 继续工作: 模式 `pointer-events: none`,它的"点击外部关闭它",它的焦点陷阱从没有到达它,你的CSS也没有. 每页有1个圆形;第二个取而代之. 当开始卡或演示升起时,它会步出出道.

| Prop | 类型 | 默认 |
| --- | --- | --- |
| `position` | `"right-bottom" | "left-bottom"` | `"right-bottom"` |
| `label` | `string` | `"Talk to our AI"` (单位:千美元)`"Need help?"` 当它只提供帮助时 |
| `content` | `"avatar" | "sparkles" | "orb"` | `"avatar"` |
| `surfaces` | `("call" | "in-app")[]` | 提供者的 |
| `modes` | `("tour" | "help")[]` | 提供者的 |
| `feature` | `string` | 提供者的 |
| `draggable` | `boolean` | `true` |
| `persistPosition` | `boolean` | `true` |
| `dismissible` | `boolean` | `true` |
| `closeLabel` | `string` | `"Hide for now"` |
| `bottom` | `number` (px) (英语) | `0` |

访客在覆盖需要的东西时可以将球体移动到另一个下角: 被拖走,它跟随指针并定居在更近的角; 有键盘聚焦,左右箭头键移动. 拖放永远不会触发点击,因此演示只打开了真实的自带. 起步卡和演示会打开了Orb的一面,因此它们从未出现在另一角. `position` 只有它开始的地方。 游客选择的角落被记住在 `localStorage`,范围为代理人;设置 `persistPosition={false}` 在下一页装入时忘记它,或者 `draggable={false}` 将矿石固定在原地.

在悬浮或焦点上的球体上会出现一个小的相近按钮(在触摸上总是可见,没有悬浮的地方). 点击它隐藏矿石 **只用于浏览器会话** ——辞退生活 `sessionStorage`,放入代理和角落,所以矿石又回到了访客的下一次访问或一个新的标签。 过 `dismissible={false}` 使矿石无法关闭 `closeLabel` 来翻译按钮的可访问标签.

这个 `label` 显示为悬浮/聚焦的工具提示。 您的 CSS 无法移动它, 因此, 如果您的应用程序在屏幕下方有条栏( 电话标签栏) , 请通过它的高度 `bottom` 球体在下面有那么多空间 设定 `content="orb"` 以没有象形文字或图标的纯活体表示。 设定 `modes={["help"]}` 或通过 `feature` d 开设目标单一特质旅游——见 [表面和模式](https://npmcn.com/package/%40demoloop/react/#readme-surfaces-and-modes)。 。 。 .

### `DemoloopButton`

内置按钮 。 接受标准 `<button>` 属性加 `children`, (中文(简体) ), `className`, (中文(简体) ), `showIcon`没有 `children` 写着 `copy.inlineButton.label` (单位:千美元)`"See it live"`) (中文(简体) ).

### `DemoloopSection`

满出血的部分 模糊的相遇风格的背景。 将居中标题+字幕作为前置组成.

| Prop | 类型 | 默认 |
| --- | --- | --- |
| `title` | `string` | `"You ask. It shows you."` |
| `subtitle` | `string` | `"An AI agent uses the product while you watch. Pick a feature, change your mind, interrupt anytime. It adapts."` |
| `buttonLabel` | `string` | `"Start the demo"` |

### `DemoloopLiveSection`

模拟真实的现场通话视图作为营销部分. 头条/周围的复制本故意不属于这个组件——用自己部分的标记来包装.

| Prop | 类型 | 默认 |
| --- | --- | --- |
| `buttonLabel` | `string` | `"Join the live demo"` |
| `chromeLabel` | `string` | `"live demo"` |
| `agentName` | `string` | `"Demo agent"` |

### `DemoloopPreviewSection`

居中卡有浏览器-色相条,代理可视化,标记行,并有"开始演示"按钮. 头条/周围的复制本故意不属于这个组件——用自己部分的标记来包装.

| Prop | 类型 | 默认 |
| --- | --- | --- |
| `displayName` | `string` | `"Your demo agent"` |
| `tagline` | `string` | `"Will share a website and talk with you live"` |
| `buttonLabel` | `string` | `"Start the demo"` |
| `chromeLabel` | `string` | `"Live demo session"` |
| `showChrome` | `boolean` | `true` |

### `DemoloopEmbed`

代理主机启动页面的内置活-demo iframe——没有覆盖. 当您希望演示直接生活在一页而不是CTA之后时使用此功能.

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `aspectRatio` | `string` | `"16/10"` | CSS的外观比. 忽略当 `height` 已经设定. |
| `height` | `string | number` | —— 说 | 显高(数字为px). 有用于出满出血入地. |
| `framed` | `boolean` | `true` | 将iframe包装在有环和阴影的圆形卡片中. |
| `title` | `string` | `"Demo"` | Iframe无障碍标题. |

直到提供商拥有 `agentId` 牌是空的,没有Iframe。 iframe的url载 `iframe=1`显示它嵌入了演示, 从而让自己处于边缘.

```tsx
<DemoloopProvider agentId="agt_xxx">
  <DemoloopEmbed aspectRatio="16/9" />
</DemoloopProvider>
```

### `useDemoloop()`

虎克回来了 `{ agentId, url, avatarUrl, theme, surfaces, modes, open, close }`用它来建立自己的触发器. `url` 是代理主机的起始页面作为链接(什么 `DemoloopEmbed` 画框, 和什么平地 `<a>` 可以指向: 它携带 `lang`, (中文(简体) ), `email`, (中文(简体) ), `theme` 财务报告和审定财务报表 `feature` 当设置,和 `mode=support` 当第一个模式是 `"help"`。 。 。 .

`open(options?)`数字 :

-   为提供商打开 Demoloop 的起步卡 `surfaces` 财务报告和审定财务报表 `modes`,除非 `options` 点击时覆盖它们。 它只问访客 留下什么 **直接进去** 当没有选择时:一个表面、一个模式和一个已知模式 `email` 立即启动呼叫.
-   `options` 实值 `{ source?: string; surfaces?: DemoloopSurface[]; modes?: DemoloopMode[]; feature?: string }`。 。 。 . `source` 交给供应商 `onOpen` 回调( 默认为 `"custom"`,参见 [跟踪](https://npmcn.com/package/%40demoloop/react/#readme-tracking)) (中文(简体) ).
-   回返a `Promise<boolean>`数字 : `true` 一旦打开 交给页面的脚本, `false` 当它不能是(没有代理,脚本不会加载,或者 `close()` 先来 它从不拒绝,因此一个无视它的触发器是好的;习惯可以在它没有打开的时候说出.
-   没有 `agentId` 参数: Demoloop 的脚本每页运行一个代理 .

`close()` 将卡片取出,或演示会从页面取出. 当用户也签名时调用它:卸载提供者不会故意结束运行的演示,因为您的应用程序本身的导航会卸载它.

## 一个脚本,每个演示

每个演示,一个在你的页面上的呼叫, 或代理 在访客自己的标签,打开一个脚本: Demoloop's `https://app.demoloop.ai/embed/v1.js`。 。 。 . `DemoloopProvider` 装入( 从您的 `baseUrl`'来源,每页一次)和每个触发器都叫它 `window.Demoloop.open({ surfaces, modes, feature, lang })`,在页面上显示Demoloop的起步卡。 SDK没有自己的模式.

-   **每页挂载提供者** 操作程序, 不仅仅是在触发器所在的地方: 脚本是在重新装入或全页导航后带回运行演示.
-   **`loadScript="open"`** 将脚本从您的页面中保存下来,直到它被使用:它装入了第一个打开的脚本,或者当演示文稿已经在此标签中运行时挂载(所以重新装入仍然会重新装入它). Demoloop的负载没有给从未开始演示的访客,除非页面有一个 `DemoloopFloatingOrb`:脚本所画出来,所以作为圆形上架来加载. 取舍:德莫洛普的安装检查("部署"页面)只听到启动一个的浏览器的声音.
-   **`email` 财务报告和审定财务报表 `name` 被传递作为谁的访客** (单位:千美元)`name` 只有一个 `email`因此,他们也没有被要求。 当打开的脚本到达时,它们会被读取,所以在装入时到达的道具仍然数起. 没有 `email` 无论您的应用程序直接告诉了脚本(`window.Demoloop.identify`留下来.
-   **每页一个特工.** 脚本运行它所装入的第一个代理;另一个代理的提供者不切换(控制台说一次如此).
-   **`onOpen` 一旦打开脚本就开火**,从不为无法装入的脚本.
-   **点击一次即时得到回答,甚至在脚本上架之前.** 自 2.2.0起,在脚本仍在加载时打开(点击一页第一秒,或慢接上),即刻取出脚本自己的"接通""接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"的接通"接通"接通"接通"接通"接通"的接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接通"接"接"接接接"接"接"接"接"接"接"接"接"接"接通"接接"接接接接"接"接"接"接"接接接"接"接"接接接接"接"接"接"接"接"接"接接接"接"接"接"接 剧本一出就在同一地段接手. 如果它从不装货,瓷砖 说再次尝试。 超过一个脚本,SDK画出一文不值:脚本显示出其瓦片本身.

### 内容-安全政策

如果您的页面发送 CSP, 它必须允许 `https://app.demoloop.ai` 内 **`script-src`** (脚本), **`frame-src`** (起始卡和演示为帧)和 **`connect-src`** (剧本向它汇报). 被屏蔽的脚本(没有这些脚本的CSP,或广告屏蔽器)向访客显示"Couldn't 加载"的平板并记录出错; 再试一次,或者下一个打开, 重新装入它.

```
script-src 'self' https://app.demoloop.ai;
frame-src 'self' https://app.demoloop.ai;
connect-src 'self' https://app.demoloop.ai;
```

在您已有的指示中添加这些来源; 上面的行仅显示 Demoloop 部分 。 麦克风需要.. `Permissions-Policy` 说明 [上文](https://npmcn.com/package/%40demoloop/react/#readme-the-microphone-and-your-permissions-policy)。 。 。 .

## 表面和模式

一个开放的提供两件事, 既设定在提供者上, 也设定在每个触发器或每点击一次的可压倒性:

-   **`surfaces`: 演示运行的地方.**
    -   `"call"` (默认):代理在您的演示账户上共享屏幕, 在您的页面上调用 。 到处跑.
    -   `"in-app"`: 访客的经纪人 **自己的登录标签**在他们真实的账户上 页面上有一个小的呼叫部件 只有在代理程序启动时,你的应用程序地址在Demoloop(确切来源)中列出, `https://app.example.com`; 列出每个子域。 在其他地方,它被排除在游客提供的东西之外。 特工按照访客的意愿操作你的应用程序,所以它可以做任何他们能做的事情:它可能不会做的是设置在特工在德莫洛普的护栏上.
-   **`modes`:演示是用来做什么的.**
    -   `"tour"` (默认):产品被引导行走.
    -   `"help"`: 反应性服务台,其中经纪人回答访客的问题而不是进行巡演.

数个值按给出的顺序给出,卡会要求访客选择. **一个表面,一个模式和一个 `email`** 所以马上打个电话.

```tsx
// A support bubble for the signed-in app
<DemoloopProvider agentId="agt_xxx" surfaces={["in-app"]} modes={["help"]} email={user.email} name={user.name}>
  {children}
  <DemoloopFloatingOrb /> {/* label defaults to "Need help?" */}
</DemoloopProvider>
```

每个触发器,超过提供者的:

```tsx
<DemoloopProvider agentId="agt_xxx">
  {children}
  {/* A targeted single-feature tour */}
  <DemoloopFloatingOrb feature="wbf_xxx" label="See this feature" />
</DemoloopProvider>
```

```tsx
// Your own trigger, opting into a mode for this click
const { open } = useDemoloop();
<button onClick={() => open({ source: "pricing_help", modes: ["help"] })}>
  Ask a question
</button>
```

A 类 `feature` 缩窄 a **旅游** 到一个功能(或一页):它是Demolooop中一个功能的ID,完全适合您直接投入电子邮件的链接。 帮助会话忽略了它.

## 复制

SDK使生命在一个被打入的物体中的每一个字符串, `DemoloopCopy`子集为 `copy` 提供方,其余为英文.

```tsx
import { DemoloopProvider, type DemoloopCopyInput } from "@demoloop/react";

const es: DemoloopCopyInput = {
  floatingOrb: { label: "Habla con la IA", moveHint: "muévelo con las flechas" },
};

<DemoloopProvider agentId="agt_xxx" copy={es}>
```

这些团体是: `floatingOrb`, (中文(简体) ), `inlineButton`, (中文(简体) ), `section`, (中文(简体) ), `liveSection`, (中文(简体) ), `previewSection` 财务报告和审定财务报表 `embed`。开始卡和呼叫是Demoloop自己的,用卡打开的语言(`lang`故他们绝没有团体。 因为类型是关闭的,所以一个翻译是作为整体输入的 `DemoloopCopy` 是编译器的检查之一: 你没有翻译的每个字符串都是你看到的错误, 而不是你在生产中发现的流出英文单词 。 包括新版本添加的字符串,所以升级后会告诉你需要翻译什么:

```tsx
import type { DemoloopCopy } from "@demoloop/react";

// Every group, every key. Leave one out and this does not compile.
const es: DemoloopCopy = {
  floatingOrb: { label: "Habla con la IA", /* … */ },
  // …
};
```

传播 `defaultCopy` 输入( e)`{ ...defaultCopy, floatingOrb: { ...defaultCopy.floatingOrb, close: "Cerrar" } }`)用英文填满每个洞并开关检查. 故意部分翻译也行 `DemoloopCopyInput` 已经覆盖.

单个组件仍然取自自己的标签道具,而那些为那一个实例而取胜的——一个页面上有不同标签的两个内在按钮是排版决定,而不是语言. `useDemoloopCopy()` 返回已解析的副本,如果您正在构建自己的触发器.

## 跟踪

`DemoloopProvider` 接受一个 `onOpen` 调回每次打开启动卡时都会点火, 不管它打开了什么: SDK的触发器之一, Orb(点击Demolooop的脚本处理本身), 或是你自己的 `open()`德莫洛普的剧本以一个 `demoloop:open` 活动 `window` (单位:千美元)`{ source, surfaces, modes, feature }`),以及 `onOpen` 因此,使用脚本标记的页面可以直接为同一事件收听。 它收到一个 `{ source, agentId, surfaces, modes, feature }` a. 信息对象(按顺序提供); `agentId` 是该页脚本实际运行的代理),所以可以在一地给分析器接线:

```tsx
<DemoloopProvider
  agentId="agt_xxx"
  onOpen={({ source, agentId }) => {
    posthog.capture("demo_opened", { source, agentId });
  }}
>
  {children}
</DemoloopProvider>
```

内建 `source` 值 :

| 构成部分 | `source` |
| --- | --- |
| `DemoloopFloatingOrb` | `"floating_orb"` |
| `DemoloopLiveSection` | `"live_section"` |
| `DemoloopSection` | `"section"` |
| `DemoloopPreviewSection` | `"preview_section"` |
| `DemoloopButton` | `"inline_button"` |
| `useDemoloop().open()` | `"custom"` |

打电话时 `open()` 直接从自己的按钮中,您可以提供更具体的源 :

```tsx
const { open } = useDemoloop();
<button onClick={() => open({ source: "hero_button" })}>
  Live demo
</button>
```

## 造型和主题

所有样式都是简单的 CSS 范围 `dl-*` 分类名称,注入 `<head>` 一次在第一舱。 要自定义, 超越您样式表中的类规则 —— 它们有低特异性( 单一类选择器) , 所以任何在我们注入后加载的规则 `<style data-demoloop>` 会赢的 通过 `[data-theme="light"]` 编号 : `[data-theme="dark"]`。 。 。 .

自0.8.0起 SDK的动画没有任何内容 浏览器必须重新油漆或铺出每个相框 没有任何动画可以让人看到它:

-   活体部分的CTA发光和相接控制器的发光被剪去,模糊的药丸被静态的圆锥旋转入内`.dl-aura-spin`两个在CTA, 一个在联合控制。 他们曾经转身 `@property` 内侧角度 `conic-gradient()` 和形态 `border-radius`,它重新撕裂和 重击他们60次一秒钟。 接合的光线只在徘徊时旋转.
-   Faux 光标为移动的全尺寸图层 `transform` (它用来动画 `top`编号 :`left`) (中文(简体) ).
-   说话的瓷砖的脉搏是 `::after` 其不透明脉冲(用于激活) `box-shadow`) (中文(简体) ).
-   CTA和加盟按钮的填充更暗而没有 `backdrop-filter`。 。 。 .
-   活体部分自己标出 `data-dl-offscreen` 既已卷起,而其中的一切事物都静止了.
-   减少运动停止了每个循环动画.

在一页闲置中,直播部分从每10人约2人的主线行走到屏幕上0.2人,没有屏幕关闭. 钩子不再做任何事情: `--dl-aura-angle` (过去), `.dl-live-section__cta-aura::before` (移动到 `.dl-aura-spin--counter`页:1 `background` 打开 `.dl-live-section__cta-aura` 或者说 `.dl-tile__join-aura` (颜色在 `.dl-aura-spin` 现在,在一个 `.dl-aura-clip`) (中文(简体) ). 说话的瓷砖的戒指被画入瓷砖内部,因此失去了外光环. 在减速运动下,平和脉冲光圈被隐藏起来,而不是作为盘子休息.

## 从1.x升级

2.0 将浮出水面的 Orb 交给 Demoloop 的脚本, 这样它就可以在您的应用程序自己的对话框上工作(参见 [`DemoloopFloatingOrb`](https://npmcn.com/package/%40demoloop/react/#readme-demoloopfloatingorb)) (中文(简体) ).

-   **`DemoloopFloatingButton` 不见了**,带有 `copy.floatingButton`, (中文(简体) ), `DemoloopPosition`,则 `"floating_button"` 来源及其来源 `.dl-floating-cta*` 课程。 使用 `DemoloopFloatingOrb`,或 `DemoloopButton` 编号 : `useDemoloop().open()` 在自己的布局中.
-   **`DemoloopFloatingOrb` 在你的页面上画什么.** 内容 `className` 道具和电线 `.dl-floating-orb*` 课程已去:Orb住在Demoloop的相框中,CSS页面无法访问. 已关闭的 Orb 保持关闭( 相同的存储密钥) .
-   **球体会到下角** 而不是留在投放的地方, 而卡和演示打开在它的侧面。 被拖过一页的一轴球体 回到了它被拖去的那一边.
-   **`onOpen` 从剧本中报告 `demoloop:open` 事件**,所以它为 Orb 自己的点击点开火。 提供商随时告诉剧本 访客是谁 `email` 或者说 `name` 更改,不仅仅是点击.
-   **矿石需要脚本.** 搭载的矿石,不管怎样 `loadScript` 说,和一个页面的 CSP 屏蔽脚本显示没有矿石.

## 从 0.x 升级

1.0去掉SDK自己的模式:每个演示都通过德莫洛普的脚本及其起步卡打开(参见: [一个脚本,每个演示](https://npmcn.com/package/%40demoloop/react/#readme-one-script-every-demo)) (中文(简体) ). 大多数嵌入体只需要下面的重命名.

| 0.x (中文(简体) ) | 1.0 国家 |
| --- | --- |
| `surface="hosted"` (默认) | `surfaces={["call"]}` (默认) |
| `surface="in-app"` | `surfaces={["in-app"]}` |
| `mode="demo"` | `modes={["tour"]}` (默认) |
| `mode="support"` | `modes={["help"]}` |
| `open(agentId, { source, feature, mode })` | `open({ source, feature, modes })`: 每页有一个代理, 所以没有 `agentId` 参数 |
| `useDemoloop().surface` 编号 : `.mode` | `useDemoloop().surfaces` 编号 : `.modes` |
| `onOpen({ source, agentId, mode })` | `onOpen({ source, agentId, surfaces, modes, feature })` |
| `baseUrl="https://app.demoloop.ai/d"` | `baseUrl="https://app.demoloop.ai"` (旧值仍然有效) |

-   **模式不见了**,用它的所有东西: `allowFullscreen`, (中文(简体) ), `confirmFullscreen`, (中文(简体) ), `confirmClose`, (中文(简体) ), `onClose`, (中文(简体) ), `copy.modal`,则 `.dl-modal-*` 分类和 `data-dl-modal-open` 属性。 Demolooop的卡片用自己设定的语言进行加载、关闭和离开 `lang`。 。 。 .
-   **`DemoloopEmbed` 编辑 `url` 从 `useDemoloop()`** 仍然帧 / 链接代理主机的启动页面 .
-   **你们的CSP** 必须允许 `https://app.demoloop.ai` 内 `script-src`, (中文(简体) ), `frame-src` 财务报告和审定财务报表 `connect-src`: 只装有主机的 0.x 仅需嵌入 `frame-src`。 。 。 .
-   **`loadScript` 财务报告和审定财务报表 `name`** 现在适用于每个演示, 不只是应用中.

## 许可证

麻省理工学院

## 常见问题

### @demoloop/react 是什么？

嵌入 Demoloop AI 演示的回放组件 \.

### 如何安装 @demoloop/react？

在项目目录运行 npm install @demoloop/react，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（\>=18）、react-dom（\>=18）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @demoloop/react 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @demoloop/react 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @demoloop/react 可以商用吗？

@demoloop/react 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @demoloop/react 的下载量有多少？

根据 npm 官方下载统计，@demoloop/react 在 2026/10/12 – 2026/11/10 这 30 天内被下载 2,865 次，日均约 96 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @demoloop/react 还在维护吗？

最新版本 2\.2\.0 发布于 2026/11/08（4 天前）；至今共发布 32 个版本，其中过去 12 个月发布了 32 个；首次发布于 2026/06/18。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

