@pinwren/widget

中文文档
0.4.0发布于 2026/11/02MITTypeScriptES Module零依赖

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

中文使用文档
文档目录9 节
  1. 安装
  2. 脚本标签(任何站点)
  3. npm
  4. API
  5. 验证了记者
  6. 可见性
  7. 会话重播
  8. 托管文件
  9. 执照

@pinwren /部件

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

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

安装

脚本标签(任何站点)

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

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

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

npm

npm install @pinwren/widget
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: "[email protected]" }, { 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.

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(). 然后仪表板将该报告者标记为 验证。永远不要将秘密发送给浏览器。

// 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 并将其附加到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 共发布 6 个版本,首次发布于 2026/10/24;过去 12 个月发布了 6 个版本。

版本发布日期距今
0.4.0latest2026/11/021 天前
0.3.02026/10/268 天前
0.2.02026/10/268 天前
0.1.12026/10/2410 天前
0.1.02026/10/2410 天前
0.0.0-stage2026/10/2410 天前

关于 @pinwren/widget 的常见问题

@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 和提交记录判断。