# @forwardpath/react 中文文档

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

版本：0\.3\.0
npm 元数据更新时间：2026-11-02T21:07:59.104Z
中文译文更新时间：2026-11-15T09:54:27.977Z
软件包许可：UNLICENSED

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

原始 npm 页面：https://www.npmjs.com/package/%40forwardpath/react
原文对照：https://npmcn.com/package/%40forwardpath/react/?lang=original
项目主页：https://github.com/ForwardPathAI/fp-os#readme
源码仓库：https://github.com/ForwardPathAI/fp-os

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

- 包体积（解压后）：80.8 kB，21 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：ai ^7，react ^19，react-dom ^19，@ai-sdk/react ^4
- 首次发布：2026-10-22T13:10:20.602Z
- 最新版本发布：2026-11-02T21:07:58.834Z
- 近 30 天下载量：4068（2026-10-16 至 2026-11-14，npm 官方下载统计）
- 已发布版本数：5（近 12 个月 5 个）

## 中文简介

反应提供者、 钩子、 聊天和反馈部件用于ForwardPath录入 .

## 安装

```sh
npm install @forwardpath/react
```

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

## README

# @ forwardpath/反应

反应组件用于ForwardPath摄入. 将您的应用程序包入 `<ForwardPathProvider>`输入 `<FeedbackWidget />` 对于浮点 "退后"按钮, `<FeedbackChat />` 用于内置聊天,或构建自己的用户界面 与 `useFeedback()`。在 `@forwardpath/js`。 。 。 .

## 安装

```sh
npm install @forwardpath/react @ai-sdk/react ai
```

`react` 财务报告和审定财务报表 `react-dom` 页:1, `@ai-sdk/react` (v4)和 `ai` (v7) 是对等的 依赖性。 不需要尾风 添加 `@forwardpath/node` 仅在您的服务器上 以 `userHash` 或从自己的路线上薄荷会议.

## 快开始

1.  在 FrontPath 门户网站中,为您的项目创建可发布密钥 。 添加 每一个来源您的应用程序运行( 例如 ). `https://app.acme.com`, (中文(简体) ), `http://localhost:3000`)并选择如何收集电子邮件。 复制密钥 (单位:千美元)`fppk_…`) (中文(简体) ).
    
2.  将您的应用程序包入提供者并导入样式一次 .
    

```tsx
// app/providers.tsx
"use client";

import { ForwardPathProvider } from "@forwardpath/react";
import "@forwardpath/react/styles.css";

type User = { id: string; email?: string | null; name?: string | null };

export function Providers({
  user,
  children,
}: {
  user: User | null;
  children: React.ReactNode;
}) {
  return (
    <ForwardPathProvider
      baseUrl="https://app.forwardpath.ai"
      publishableKey={process.env.NEXT_PUBLIC_FORWARDPATH_KEY!}
      user={user}
      appName="Acme"
      appVersion={process.env.NEXT_PUBLIC_APP_VERSION}
      environment={process.env.NODE_ENV}
    >
      {children}
    </ForwardPathProvider>
  );
}
```

3.  将部件添加到您的布局中, 在提供者内部 .

```tsx
// app/layout.tsx
import { FeedbackWidget } from "@forwardpath/react";

import { getUser } from "@/auth"; // your own auth
import { Providers } from "./providers";

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const user = await getUser(); // null when signed out
  return (
    <html lang="en">
      <body>
        <Providers user={user}>
          {children}
          <FeedbackWidget />
        </Providers>
      </body>
    </html>
  );
}
```

或让聊天在自己的一页内:

```tsx
// app/support/page.tsx
"use client";

import { FeedbackChat } from "@forwardpath/react";

export default function SupportPage() {
  return (
    <FeedbackChat
      placeholder="What went wrong?"
      onSubmitted={(report) => console.log("Filed", report.customerReference)}
    />
  );
}
```

## 可公开的密钥

可公布的密钥按设计公开. 任何人都可以从你的页面上读到, 因此它只能为它的一个项目开始录入聊天,并且只能从 允许在密钥上输入源 。 前进率限制它。 千万别把秘密藏起来 API 密钥( E)`fp_…`或钥匙的身份秘密(`fpiv_…`)在浏览器代码中.

## 记者是谁

| 你通过 | 记者 | 含义 |
| --- | --- | --- |
| `user` 财务报告和审定财务报表 `userHash` | `verified` | 您的服务器在用户签名 . |
| `user` 仅限 | `claimed` | 浏览器命名了用户. 任何人都可以发送任何ID或电子邮件,所以视之为未经核实. |
| 也没有 | `anonymous` | 无名来客. |

对于匿名的访客,提供者 保持一个随机的ID在 `localStorage` (单位:千美元)`forwardpath:anonymous-id`),所以重复访问地图给同一个记者. 在存储被屏蔽的地方,ID会持续到页面负载.

何时 `publishableKey`, (中文(简体) ), `user.id`, (中文(简体) ), `user.email` 或者说 `userHash` 变化 提供者放下缓存会话并薄荷新会话, 所以签入和 退出不需要加载页面。 一个新的 `user` 保留相同字段的天体 会议闭幕.

### 验证用户为 `userHash`

计算服务器上的散列 `createUserHash` 从 `@forwardpath/node` 和钥匙的身份秘密(`fpiv_…`,在 您创建了密钥 。 交给旁边的供应商 `user`。 。 。 .

```tsx
// app/layout.tsx (a server component)
import { createUserHash } from "@forwardpath/node";

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const user = await getUser();
  const userHash = user
    ? createUserHash({
        identitySecret: process.env.FORWARDPATH_IDENTITY_SECRET!,
        user,
      })
    : undefined;
  // Pass both on: <ForwardPathProvider user={user} userHash={userHash} …>
  return (
    <html lang="en">
      <body>
        <Providers user={user} userHash={userHash}>
          {children}
          <FeedbackWidget />
        </Providers>
      </body>
    </html>
  );
}
```

散列标志 `user.id` 财务报告和审定财务报表 `user.email`而不是这个名字。 显示相同值 你通过作为 `user`: 错配以 401 失败会话 。 无 `userHash` 用户是 `claimed`。 。 。 .

## 电子邮件表

当代理人没有给记者的邮件时,例如匿名访客或 `user` 无 `email`它在聊天中显示一个简短的形式: 电子邮件,一个可选的 名并发相. 一旦用户回答,聊天就自行进行. 虽然 窗体打开,作曲者被禁用.

设定 `contactCollection` 门户中的每个密钥 :

-   `required`:代理只有在用户发出电子邮件后才将报告归档 .
-   `optional`:表单也显示跳过.
-   `off`:经纪人从来不问.

服务器在外部报告前保存已提交的电子邮件 助理继续。 将报告人链接到请求中并包含 它们在请求元数据和线性描述中的联系方式。 键入 电子邮件被标记为自报;它不创建一个门户账户.

如果您的应用程序已经知道用户的电子邮件, 请通过 `user={{ id: user.id, email: user.email, name: user.name }}` 打开 `ForwardPathProvider`。聊天时不用再次询问.

## 从服务器验证的用户

要在您的服务器上使用您的 API 密钥进行薄荷会话, 请省略 `publishableKey` 并添加会话路由 `@forwardpath/node`编辑 提供者 POSTs `{ clientContext }` 改为 `/api/forwardpath/session` 默认 和预期 `{ token, expiresAt }` 回来 这些记者总是 `verified`。 。 。 .

```ts
// app/api/forwardpath/session/route.ts
import {
  createForwardPathClient,
  createIntakeSessionHandler,
} from "@forwardpath/node";

import { auth } from "@/auth";

const client = createForwardPathClient({
  apiKey: process.env.FORWARDPATH_API_KEY!,
  baseUrl: "https://app.forwardpath.ai",
});

export const POST = createIntakeSessionHandler({
  client,
  projectSlug: "acme-web",
  // Return the signed-in user, or null to answer 401.
  getUser: async () => {
    const session = await auth();
    if (!session?.user) return null;
    return {
      externalId: session.user.id,
      email: session.user.email,
      name: session.user.name ?? undefined,
    };
  },
});
```

```tsx
<ForwardPathProvider baseUrl="https://app.forwardpath.ai" sessionKey={userId}>
```

您的 API 密钥可以为任何用户薄荷会话 。 放在服务器上. 提供者只向ForwardPath发送短暂的会话符号.

## `<ForwardPathProvider>`

| Prop | 说明 |
| --- | --- |
| `baseUrl` | FPOS起源,例如:. `https://app.forwardpath.ai`。 。 。 . |
| `publishableKey` | 可公布的密钥( E)`fppk_…`) (中文(简体) ). 浏览器薄荷会与之相会. |
| `user` | `{ id, email?, name? }` 用于登录用户,或 `null` 给匿名访客 使用过的 `publishableKey`。 。 。 . |
| `userHash` | `createUserHash()` 从您的服务器输出 。 制造 `user` `verified`。 。 。 . |
| `sessionEndpoint` | 你的路线,薄荷一个会话。 默认 `/api/forwardpath/session`。 。 。 . |
| `getSessionToken` | 薄荷会自己。 获取 `{ clientContext }`; 返回 `{ token, expiresAt }` 或符号字符串. |
| `sessionKey` | 会话是给谁用的,例如签名的用户代号. 更改它会减少缓存会话 . |
| `appName`, (中文(简体) ), `appVersion`, (中文(简体) ), `environment`, (中文(简体) ), `custom` | 发送每个信息,使团队看到反馈的来源. |
| `fetch` | 自定义 `fetch` 每个请求. |

`getSessionToken` 胜过 `publishableKey`,获胜 `sessionEndpoint`。 。 。 .

提供商在首次使用时会将一个代币薄荷并保存在记忆中. 薄荷糖 薄荷糖 60秒前的新时间 `expiresAt`,如果API回答401. 空弦从 `getSessionToken` 保存到401号 过 `sessionKey` 这样 没有页面负载的用户切换不会再重复旧用户的会话.

## `useFeedback()`

回返 `{ messages, sendMessage, status, error, stop, retry, reset, submitted, attachments, uploading, attachmentError, attach, removeAttachment, contactRequest, submitContact }`。 。 。 .

-   `sendMessage(text)` 随任何待处理附件发送用户消息。 这个 此时不做 `contactRequest` 打开.
-   `status` 是 AI SDK 聊天状态 : `ready`, (中文(简体) ), `submitted`, (中文(简体) ), `streaming` 或者说 `error`。 。 。 .
-   `retry()` 在出错后再发送最后一个消息.
-   `reset()` 清除聊天内容.
-   `submitted` 是最近成功提交的 (单位:千美元)`{ customerReference, title, ... }`),或 `null`。 。 。 .
-   `attach(file)` 上传一个 `File` 与下一个信息一起发送。 见 [附录](https://npmcn.com/package/%40forwardpath/react/#readme-attachments)。 。 。 .
-   `attachments` 列出等待下一个消息的上传文件,以及 `removeAttachment(id)` 掉一个.
-   `uploading` 计算飞行中的上传; `attachmentError` 说为什么最后 一个失败.
-   `contactRequest` 是代理服务器打开的电子邮件请求 (单位:千美元)`{ toolCallId, canSkip }`),或 `null`。见 [电子邮件表](https://npmcn.com/package/%40forwardpath/react/#readme-the-email-form)。 。 。 .
-   `submitContact(toolCallId, { email, name? })` 接电话,或者 `submitContact(toolCallId, { skipped: true })` 何时 `canSkip` 这是真的。 这个 三进制值, 丢弃空名并拒绝无效的电子邮件 。 闲聊 然后自己继续. `<FeedbackChat>` 做这个表格给你.

每个 `useFeedback()` 呼叫自己负责谈话 来推动聊天 `<FeedbackChat>` 或者说 `<FeedbackWidget>` 显示结果,通过结果 `feedback` 道具 (英语).

```tsx
import { useFeedback } from "@forwardpath/react";

function MyChat() {
  const { messages, sendMessage, submitted } = useFeedback();
  if (submitted) return <p>Thanks! Your reference is {submitted.customerReference}.</p>;
  // ...
}
```

## `<FeedbackWidget />`

打开的固定发射器按钮 `<FeedbackChat />` 在一个面板。 打开它 一次,在提供者内部.

| Prop | 说明 |
| --- | --- |
| `position` | `bottom-right` (违约)或 `bottom-left`。 。 。 . |
| `label` | 发射器文本和面板标题。 默认 `Feedback`。 。 。 . |
| `title` | 独立于发射装置而覆盖面板标题. |
| `launcherIcon` | 发射口标记的反应节点. 默认为 `assistantIcon`,然后是一个内置聊天标记。 过 `null` 藏起来. |
| `defaultOpen` | 打开挂载面板 . |
| `className` | 添加到部件的根元素中 . |
| `style` | 内置样式并输入 `--fp-*` 部件根上的主题变量. |

还要花很多时间 `<FeedbackChat />` 道具 (英语). `className` 财务报告和审定财务报表 `style` 应用 转到部件根后,主题由面板继承。 埃克还是 关闭按钮关闭面板并返回焦点到发射台。 闭幕 隐藏面板而不结束对话.

## `<FeedbackChat />`

| Prop | 说明 |
| --- | --- |
| `placeholder` | 作曲占位符. |
| `assistantName` | 在助理信件和部件标题上显示名称。 默认 `ForwardPath assistant`。不改变模式或指示. |
| `assistantIcon` | 装饰性反相节点,例如带有SVG或图像 `alt=""`。用于欢迎状态、助理消息和部件标题。 过 `null` 藏起来. |
| `welcomeTitle` | 头一通消息前去. 默认 `How can we help?`。 。 。 . |
| `welcomeMessage` | 在第一个消息之前支持文本 。 不发送消息或启动会话 . |
| `onSubmitted(report)` | 每成功提交一次. |
| `className` | 被添加到根元素中. |
| `style` | 内置样式并输入 `--fp-*` 主题变量. |
| `feedback` | A 类 `useFeedback()` 而不是聊天时自己做的. |

以换行符将信件变成纯文本 。 信件中的 HTML 显示为 文本并永远不运行。 当代理请求电子邮件时, 表格会显示在内 它的讯息.

## 附录

用户可以在纸张剪贴按钮中附加文件,或将其放入 闲聊。 每个文件一次上传,并显示为作曲家之上的芯片,直到 下一个信息发送它。 图像附件向代理显示, 所有 附件可以添加到已备案的请求中.

在上传前, 聊天检查每个文件 :

-   低于 10 MB(上传请求,包含框架,必须符合 10 MB),
-   是 PNG、 JPEG、 WebP 或 GIF 图像、 PDF、 纯文本、 CSV 或 JSON 文件( 或 没有类型, 上传为 `application/octet-stream`),以及
-   不把谈话 超过10附件.

从自己的代码附加一个文件, 例如日志导出, 调用 `attach`数字 :

```tsx
"use client";

import { FeedbackWidget, useFeedback } from "@forwardpath/react";

export function Feedback({ getLogs }: { getLogs: () => string }) {
  const feedback = useFeedback();
  async function attachLogs() {
    await feedback.attach(
      new File([getLogs()], "app-log.txt", { type: "text/plain" }),
    );
  }
  return (
    <>
      <button onClick={attachLogs}>Attach logs</button>
      <FeedbackWidget feedback={feedback} />
    </>
  );
}
```

`attach` 拒绝检查或上传失败,并设定 `attachmentError`。 。 。 .

## 屏幕抓取

“ Capture 屏幕” 按钮要求浏览器共享屏幕、 窗口或 选项卡 `getDisplayMedia`,将一个框架保存为 `screenshot-<ISO time>.png`, (中文(简体) ), 停止共享并附加图像。 没有其他记录.

-   浏览器每次都会提示用户. 取消提示无效 .
-   按钮只显示在哪里 `navigator.mediaDevices.getDisplayMedia` 存在: 安全上下文( HTTPS 或 `localhost`)在桌面浏览器中. 多数 移动浏览器不支持.
-   在iframe中,母页必须允许: `<iframe allow="display-capture">`A级 `Permissions-Policy` 标题 块 `display-capture` 也禁用它 .

## 他们

标记每个执行而不替换聊天 UI :

```tsx
<FeedbackWidget
  label="Help"
  title="Acme support"
  assistantName="Acme assistant"
  assistantIcon={<img src="/acme-mark.svg" alt="" />}
  welcomeTitle="How can we help?"
  welcomeMessage="Tell us what's happening or what you'd like to improve."
  style={{
    "--fp-accent": "#0f766e",
    "--fp-accent-foreground": "#ffffff",
    "--fp-radius": "16px",
    "--fp-panel-width": "420px",
  }}
/>
```

发射器使用相同的标记,除非你提供 `launcherIcon`全部数据 图标为装饰; `label`, (中文(简体) ), `title` 财务报告和审定财务报表 `assistantName` 提供 可读文本。 选择带有可读对比度的口音和前景对 在你的应用的光和暗的主题. `FeedbackStyle` 导出为共享 在部件和内置聊天实例之间键入样式.

每个课从头开始 `fp-`设置这些变量 `:root`,一个祖先 或者说 `.fp-root`数字 :

```css
:root {
  --fp-accent: #0f766e;
  --fp-accent-foreground: #ffffff;
  --fp-bg: #ffffff;
  --fp-fg: #111827;
  --fp-radius: 8px;
  --fp-font: "Inter", sans-serif;
  --fp-z-index: 1000; /* widget stacking order */
  --fp-panel-width: 400px;
  --fp-panel-height: 620px;
}
```

添加 `data-fp-theme="dark"` 给祖先(如:. `<html>`) 对于黑暗 默认值。 如果你准备好了 `--fp-bg` 或者说 `--fp-fg` {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}你也可以把它们放在下面 你的黑暗模式选择者.

## 常见问题

### @forwardpath/react 是什么？

反应提供者、 钩子、 聊天和反馈部件用于ForwardPath录入 \.

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

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

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

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

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

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

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

@forwardpath/react 使用 UNLICENSED 许可。作者声明为 UNLICENSED，即不授予公开使用许可（与公共领域的 Unlicense 不同）。使用前需获得作者授权。以上为概括，不构成法律意见，请以许可原文为准。

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

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

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

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

