astro-feedback-board: anonymous feedback for Astro sites

astro-feedback-board started as the feedback system of Fuseplan. I pulled it out of the app so other Astro sites can use it, this blog included. Scroll to the end of this post and you’ll see the reaction buttons it adds.

What’s in the package

Visitors post feedback without an account, and an admin approves it in a small panel. One Cloudflare Worker with a D1 database serves every site, and each site gets its own origins and moderation settings. The package ships five Astro components:

ComponentWhat it does
FeedbackButtonFloating or inline button that opens the feedback form
FeedbackAskInline card with one question, like “Which feature is missing?”
FeedbackBoardPublic board with votes, filters, replies and status per topic
FeedbackCommentsdev.to-style reactions and moderated comments under an article
FeedbackPromptAsks for feedback after some minutes of active use

Merging duplicates and reports are not built yet.

What this blog uses

Only the reactions. Comments are switched off, so nothing here needs moderation:

---
import { FeedbackComments } from "astro-feedback-board/components";
---

<FeedbackComments
  site="slashgordonblog"
  endpoint="https://feedback.dieck-labs.de"
  lang="en"
  comments={false}
/>

The article key defaults to the page path, so the English and German version of a post count separately. The buttons collect clicks and send them in one request 2 seconds after the last click, so trying out all five costs one request.

Spam without an account

Every form has a honeypot field, a minimum of 3 seconds between rendering and sending, and an ALTCHA proof of work that the browser solves in the background. Reactions go through the same checks.

The Worker also limits by IP, but it never stores one. It hashes the IP with a random salt per day, stores the salt in D1 and deletes it after two days. After that, nobody can trace the stored hashes back to an IP, including me. Each IP gets at most 10 posts per day and one of each reaction per article and day. If spam gets through anyway, pausing the site in the admin panel blocks all posts, votes and reactions until you unpause it.

The components set no cookies and load no third-party scripts or fonts. They only write to localStorage after the visitor ticks “remember me on this device”, and a “forget” button deletes all of it again, including the data on the Worker.

Setup

npm install astro-feedback-board

The Worker needs a D1 database, created with --jurisdiction eu so the data stays in the EU, an ALTCHA_HMAC_KEY secret and Cloudflare Access in front of /admin. docs/deploy.md walks through it step by step. For German sites there is also a template for the privacy policy in docs/datenschutz.md.

How did you like this article?