Global “Like / Stomp” Widget—No DB, No Fees
Real-Time Reactions for Hexo
GitHub Issue + Vercel Function → everyone shares the same count.
Setup in 3 Steps (click)
1. **GitHub** • Create an Issue titled `__VOTES__`, body `{}` → note its number. • Generate a PAT with **public_repo** scope. 2. **Backend repo + Vercel** • Import repo into Vercel → Env var `GH_TOKEN=Demo Widget
Click 👍 or 👎 to see the counter update (shared across browsers).
0
Show serverless file
```js import { Octokit } from "octokit"; const octokit = new Octokit({ auth: process.env.GH_TOKEN }); const owner = "YourGitHubUser"; // ← edit const repo = "your-hexo-site-repo"; // ← edit const ISSUE = 3; // ← edit export default async function handler(req, res){ res.setHeader("Access-Control-Allow-Origin","*"); res.setHeader("Access-Control-Allow-Methods","GET,POST,OPTIONS"); res.setHeader("Access-Control-Allow-Headers","Content-Type"); if(req.method==="OPTIONS") return res.status(200).end(); const { key, delta } = req.method==="GET" ? {key:req.query.key} : req.body; if(!key) return res.status(400).json({error:"key missing"}); const issue = await octokit.rest.issues.get({ owner, repo, issue_number:ISSUE }); const data = JSON.parse(issue.data.body || "{}"); if(req.method==="POST"){ data[key]=(data[key]||0)+Number(delta||0); await octokit.rest.issues.update({ owner, repo, issue_number:ISSUE, body:JSON.stringify(data) }); } res.json({count:data[key]||0}); }All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.