Skip to content

Prototype: Bluesky-authenticated comments on blog posts - #76

Open
lksbrssr wants to merge 2 commits into
mainfrom
feat/bluesky-comments
Open

Prototype: Bluesky-authenticated comments on blog posts#76
lksbrssr wants to merge 2 commits into
mainfrom
feat/bluesky-comments

Conversation

@lksbrssr

Copy link
Copy Markdown
Collaborator

What this is

A prototype of reader comments on blog posts, authenticated with Bluesky — the "lightweight, no password, but you say who you are" model. It reuses the site's existing AT-Protocol OAuth (/api/login, /api/oauth/callback, useAuth) so signing in is one click with a Bluesky handle, and every comment carries a real, verified identity (handle, display name, avatar) instead of a free-text name box.

Screenshots

Empty state + sign-in box (bottom of a blog post):
Bluesky comments widget

How it works

  • Identity: reuses existing Bluesky OAuth. The commenter's identity is read from the verified server session — never from request input — so impersonation isn't possible.
  • Storage: comments are written to the plresearch.org service repo (same app-password service agent already used by the pages / opportunity-spaces editors) under a new org.plresearch.comment collection.
  • Read path: a single listRecords call filtered by post slug — no firehose/indexer dependency, so it works the moment this merges.
  • Moderation: authors can delete their own comments; admin DIDs can delete any. One repo = one place to moderate.
  • Return-to-post: login now passes an optional same-origin returnTo through the OAuth state param, so readers land back on the post after signing in (backward-compatible — existing login(handle) callers unchanged).

Files

File Change
src/lib/lexicons.ts new org.plresearch.comment collection + types
src/lib/comments.ts server helper: service agent, list/create/delete
src/app/api/comments/route.ts GET (public) / POST (auth) / DELETE (author or admin)
src/components/Comments.tsx client widget: thread + sign-in + composer
src/app/blog/[slug]/page.tsx render <Comments> (skipped for external-stub posts)
src/app/api/login, oauth/callback, src/lib/atproto.tsx optional returnTo after login
.env.example documents that comments reuse ATPROTO_HANDLE/ATPROTO_PASSWORD

Deliberate prototype tradeoffs / open questions

  • Single-repo storage (vs. each user's own repo) was chosen for a zero-infra read path and easy moderation. If you'd rather comments live in each commenter's repo, that needs the GraphQL indexer to index org.plresearch.comment — happy to switch.
  • Spam: real Bluesky identity already blocks impersonation and most drive-by spam. Not yet added: Cloudflare Turnstile, rate limiting, per-post disable. Easy follow-ups.
  • No optimistic moderation queue — comments post live. Could gate behind approval if desired.
  • Requires ATPROTO_HANDLE/ATPROTO_PASSWORD to be set in the deployment (already used elsewhere). Without them the API returns a clean "not configured" message.

Verified

  • tsc --noEmit clean
  • next build succeeds; /api/comments registered as a dynamic route; all 310 static pages generate
  • Widget renders on a real post (screenshot above)

@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
plrd.org Ready Ready Preview, Comment Jul 21, 2026 3:45pm

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant