# @pinwren/widget 中文文档

规范地址：https://npmcn.com/package/%40pinwren/widget/

版本：0\.4\.0
npm 元数据更新时间：2026-11-02T04:00:58.105Z
中文译文更新时间：2026-11-02T04:35:29.715Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40pinwren/widget
原文对照：https://npmcn.com/package/%40pinwren/widget/?lang=original
项目主页：https://pinwren.xride-labs.in/
源码仓库：https://github.com/Krithik-m-codes/pinwren

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

- 包体积（解压后）：703 kB，24 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2026-10-24T07:17:52.835Z
- 最新版本发布：2026-11-02T04:00:57.850Z
- 已发布版本数：6（近 12 个月 6 个）

## 中文简介

Pinwren反馈小部件：figma风格的固定评论和任何网站的注释错误报告

## 安装

```sh
npm install @pinwren/widget
```

也可以使用：`pnpm add @pinwren/widget`、`yarn add @pinwren/widget`、`bun add @pinwren/widget`

## README

# @pinwren /部件

这个 [Pinwren](https://pinwren.xride-labs.in/) 反馈小部件：figma风格的评论固定在您的网站的任何元素， 带注释的bug报告与控制台，网络和（可选）会话回放-发送到您的自托管 或云Pinwren服务器。麻省理工学院的许可。

它运行在一个封闭的影子DOM中，永远不会进入你的页面，并加载它的重要部分(截图引擎， 注释编辑器，侧板，重播记录器，翻译)，只有当访问者需要他们。

## 安装

### 脚本标签（任何站点）

```html
<script src="https://feedback.example.com/widget.js" data-project="pk_live_xxx" async></script>
```

`feedback.example.com` 是你的Pinwren服务器；项目密钥来自 **项目›安装** 在 仪表板。页面的原点必须在项目允许的原点中。

| 属性 | 意义 |
| --- | --- |
| `data-project` | 公共项目密钥（必需） |
| `data-endpoint` | API的来源，当它不同于哪里 `widget.js` 的服务（例如CDN） |
| `data-locale` | 用户界面语言(`en`， `es`， `fr`， `de`， `pt-BR`， `it`， `ja`， `hi`， `nl`， `zh`， `ru`） |
| `data-accent` | 发射器颜色，十六进制 |
| `data-theme` | `light` 或者 `dark`;否则访问者的系统设置 |
| `data-url-pattern` | 页面范围，例如： `/product/:id` -图钉在每个匹配它的页面上共享 |
| `data-force-show` | 即使项目的可见性规则会隐藏小部件，也要显示它 |
| `data-nonce` | 小部件添加的脚本的CSP nonce |
| `data-allow-replay-in-privacy-mode` | 在隐私模式下保持会话回放（您负责同意） |

### npm

```sh
npm install @pinwren/widget
```

```ts
import { identify, init, on, open } from "@pinwren/widget";

init({ projectKey: "pk_live_xxx", endpoint: "https://feedback.example.com" });
identify({ id: "user_42", name: "Maria Lopez", email: "maria@example.com" }, { signature });
on("submit", ({ number }) => console.log(`Feedback #${number} sent`));
open("bug");
```

npm入口是一个约1kb的ESM加载器，带有TypeScript类型。 `init()` 增加了 `<endpoint>/widget.js` -构建 您的服务器已发货，因此小部件总是与您的服务器版本匹配，并对之前的每个调用进行排队 它已经装载完毕。在服务器端呈现期间导入是安全的：没有任何影响 `window` 直到你打电话 功能在浏览器中。对于React和Next.js使用 [`@pinwren/react`](https://www.npmjs.com/package/@pinwren/react).

## API

| 呼叫 | 它是做什么的 |
| --- | --- |
| `init(options)` | 启动小部件（每个页面一次）。选项: `projectKey`， `endpoint`， `accent`， `locale`， `urlPattern`， `forceShow`， `allowReplayInPrivacyMode`， `nonce` |
| `open(mode?)` | 打开菜单，或 `"comment"`， `"bug"`， `"panel"` 或者 `"page"` （整页的评论）直接 |
| `close()` | 关闭所有打开的 |
| `identify(user, { signature? })` | 从你的应用程序中预填充记者； `null` 忘记他们 |
| `setPageScope({ urlPattern })` | 更改页面范围(`null` 清理);页面上的大头针被重新列出 |
| `setMetadata(object)` | 上下文（plain JSON对象，≤14kb）随每个报告和评论发送； `null` 清除它 |
| `show()` / `hide()` | 显示或隐藏小部件，覆盖项目的可见性模式 |
| `on(event, handler)` | `open`， `close`， `submit` （`{ id, number, kind }`)， `error` （`{ message }`)， `ready`． 返回退订 |
| `destroy()` | 删除一切：UI，监听器，控制台/网络包装器，会话回放 |

使用script标记，开启相同的功能 `window.Pinwren`;在脚本加载之前进行的调用可以 排队 `window.Pinwren = { q: [["identify", user], ["open", "bug"]] }`.

### 验证了记者

计算 `signature` **在服务器上** - hex用户的HMAC-SHA256 `id` 与项目的身份保密 （仪表板：项目设置›身份）-并将其传递给 `identify()`． 然后仪表板将该报告者标记为 验证。永远不要将秘密发送给浏览器。

```ts
// Node, on your server
import { createHmac } from "node:crypto";
const signature = createHmac("sha256", process.env.PINWREN_IDENTITY_SECRET!).update(user.id).digest("hex");
```

### 可见性

设置在仪表板(**Widget›可视性**); `forceShow` 覆盖两种:

-   **环境→非生产** 在生产主机上隐藏小部件。不生产: `localhost`， `*.localhost`，环回和私有网络ip(127。x, 10。192.168 x。172.16 - -31. x, x, `::1`)，后缀 `.local`， `.test`， `.internal`, `staging`， `stage`， `preview` 或者 `dev` 子域(`dev.example.com`， `preview-42.example.com` ——但 `example.dev` 是生产)。其他一切都是生产。
-   **最小视口宽度** 将它隐藏在较窄的窗口上（当窗口变大时它会回来）。

## 会话重播

当项目启动时(**捕获›会话回放**)，小部件记录页面的最后30-120秒 与 [rrweb](https://github.com/rrweb-io/rrweb) 并将其附加到bug报告中。录音保存在 Page的内存，只与报告一起发送；记者在“我们将发送的内容”中看到它，可以忽略它。 每个输入都被屏蔽；元素和类 `pinwren-block` 或者 `data-pinwren-ignore` 没有记录； `pinwren-mask` / `data-pinwren-mask` （以及项目的掩码选择器）的文本被替换。隐私模式 除非页面设置，否则关闭重播 `allowReplayInPrivacyMode`.

## 托管文件

`dist/` 持有 `widget.js` 加上内容散列块(`widget-panel.<hash>.js`， `widget-capture.<hash>.js`,……) 中列出的 `dist/manifest.json`． 服务 `widget.js` 使用短缓存(`Cache-Control: public, max-age=300`） 和散列文件 `Cache-Control: public, max-age=31536000, immutable`． 块从 目录 `widget.js` 的CDN副本 `dist/` 适用于 `data-endpoint` 指着你的 服务器。

内容安全策略：允许您的Pinwren起源 `script-src`， `connect-src` 和 `img-src` (加上 `data:` 和 `blob:` 在 `img-src` 截图)。

## 执照

麻省理工学院。中列出了捆绑的第三方代码（SnapDOM、finder、rrweb） `dist/THIRD_PARTY_NOTICES.md`.

## 常见问题

### @pinwren/widget 是什么？

Pinwren反馈小部件：figma风格的固定评论和任何网站的注释错误报告

### 如何安装 @pinwren/widget？

在项目目录运行 npm install @pinwren/widget，或使用 pnpm add / yarn add / bun add。

### @pinwren/widget 支持 TypeScript 吗？

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

### @pinwren/widget 支持 ESM 还是 CommonJS？

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

### @pinwren/widget 可以商用吗？

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

### @pinwren/widget 还在维护吗？

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

