@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-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
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.