Emoji Reactions
为你的文章添加表情回应按钮。每位读者只能回应一次,可选显示数量,不使用 Cookie,也不保存原始 IP。
插件
Emoji Reactions
为你的文章添加表情回应按钮。每位读者只能回应一次,可选显示数量,不使用 Cookie,也不保存原始 IP。
描述
Reactions 会为你的文章添加表情回应按钮(默认是 💗 🤔 😗)。 每位读者对每篇文章只能选择一个回应:再次点击会取消,点击另一个则会切换。
功能
- 最多 6 个按钮,在管理页面中配置(
key=emoji:label)。 - 可在每个表情旁显示标签,也可公开显示数量。
- 管理页面会列出回应最多的 10 篇文章。
- 管理页面跟随管理后台的语言(英语或日语)。
- 无需额外数据库:数据保存在插件自己的 EmDash 存储中。
- 不请求任何权限,也不请求网络访问。
隐私
- 读者通过其 IP 地址和 User-Agent 的 SHA-256 哈希值(附带每个站点随机的盐)来识别。IP 和 User-Agent 本身绝不会被保存。
- 每次投票保存:文章 ID、哈希值、所选回应和时间戳。不使用 Cookie。
注意: 插件本身不会渲染任何内容。安装后,请把
Reactions.astro组件添加到你的文章模板中(参见安装)。
要求
- Cloudflare(D1)上的 EmDash 1.x
- Workers Paid 套餐(沙盒插件在 Worker Loader 绑定中运行)
安装
1. 安装插件
通过 Open in EmDash 从本页安装 Reactions,或从源码构建:
pnpm install
pnpm run build # dist/
从源码构建时,把该软件包添加到你的站点(pnpm add file:../emdash-plugin-emoji-reactions),并在 astro.config.mjs 的 sandboxed: [reactions] 下列出它。
2. 启用插件沙盒
沙盒插件需要 Worker Loader 绑定。在 wrangler.jsonc 中(模板里已被注释掉):
"worker_loaders": []
确保 src/worker.ts 导出了 PluginBridge(*-cloudflare 模板已经导出),并且 astro.config.mjs 设置了 sandboxRunner: sandbox()。
3. 把按钮添加到文章模板中(必需)
把 site-snippets/Reactions.astro 复制到 src/components/,并放在文章页面上:
---
import Reactions from "../../components/Reactions.astro";
// `post` comes from getEmDashEntry()
---
使用 post.data.id(数据库 ID),不要使用 post.id(slug)。文章重命名时 slug 会改变,而翻译后的 slug 含有 /,插件会拒绝它。
属性:contentId(必填)、heading(空字符串则隐藏)、label(按钮组的无障碍名称)。在 CSS 中设置 --rx-accent 以匹配你的强调色。
4. 选择你的按钮
打开管理后台侧边栏中的 Reactions 并编辑该字段,例如:
love=💗:Love, hmm=🤔:Hmm, whistle=😗:Whoa
最多 6 项。键以小写字母开头。数量按键保存:重命名键会开始一个新按钮;删除一个键会隐藏它,但保留其数量。
常见问题
按钮没有出现在我的站点上
- 检查
Reactions.astro是否已添加到你的文章模板中。插件本身不会渲染任何内容。 - 打开浏览器控制台。失败信息会以
[reactions] state: HTTP 403 CSRF_REJECTED ...的形式记录。 - 如果你是把
dist/复制到站点中,而不是安装软件包,请检查dist/index.mjs是否包含"routes"。没有它,EmDash 会把公开路由当作私有路由并拒绝请求。
我能隐藏数量吗?
可以。在管理页面中关闭 Show counts。此后公开 API 也不会包含数量,因此无法从页面中读取。它们仍会继续被统计,你在管理页面中依然可以看到。
我家里或办公室的两个人被算作一位读者
使用同一个 IP 且使用同一浏览器的读者会被视为一个人。这只是一个随意的回应按钮,而不是投票系统。
有人能刷这个按钮吗?
每位读者对每篇文章只有一个回应,因此重复点击只会切换它。不过这些路由是公开的。如有需要,请为 /_emdash/api/plugins/reactions/react 添加一条 Cloudflare 速率限制规则。
它能在本地开发中使用吗?
可以。当没有可用的客户端 IP 时,浏览器会改为发送保存在 localStorage(rx-visitor)中的随机 ID。
安全
报告漏洞
请通过 GitHub 私密漏洞报告私下报告安全问题, 不要发布在公开的 issue 中。
插件可以访问什么
- 不请求任何权限,也不请求网络访问。 插件无法读取或更改其自身存储之外的你的内容、媒体、用户或设置,也无法调用其他服务。
- 它只把数据保存在自己的 EmDash 存储中:每篇文章的数量、每次投票一条记录,以及它的按钮设置。
保存的读者数据
- 读者 IP 地址和 User-Agent 的截断 SHA-256 哈希值,并结合每个站点随机的盐。IP 地址和 User-Agent 本身从不被保存。
- 每次投票:文章 ID、该哈希值、所选回应和时间戳。不使用 Cookie。
公开路由
state(GET)和 react(POST)是公开的。两者都会校验输入:contentId 必须匹配 [A-Za-z0-9_\-:.],回应必须是已配置的键,请求体上限为 1 KB。管理路由是私有的。为限制滥用,请为 /_emdash/api/plugins/reactions/react 添加一条 Cloudflare 速率限制规则。
更新日志
0.2.1 — 2026-10-18
- 添加了注册表图标。
0.2.0 — 2026-10-15
在 EmDash 插件注册表上的首次发布。
- 管理页面中新增 Show labels 和 Show counts 开关。标签默认隐藏,并保留为工具提示和屏幕阅读器文本。隐藏数量后,公开 API 也不会包含它们。
- 需要 EmDash 1.x。按钮设置移至
ctx.settings;在 0.1.x 中保存的按钮会被沿用。 - 管理页面跟随管理后台的语言(英语或日语)。默认标签现在为英语(
Love/Hmm/Whoa);键保持不变,因此现有数量仍然保留。 Reactions.astro:把失败信息记录到浏览器控制台,而不是悄悄隐藏;新增label属性和--rx-accentCSS 变量;并记录了传入post.data.id的用法。pnpm run test现在以构建结束,因此dist/始终包含公开路由声明。
0.1.0
- 初始版本(未发布到注册表)。