Table of contents
Open Table of contents
Overview
This post documents how to build an automated comment system for a static blog using the Bluesky API. The workflow is simple: every new post automatically creates a discussion thread on Bluesky, and comments are rendered asynchronously on the blog page.
Publishing Pipeline
To ensure social platforms can correctly scrap preview cards (Open Graph), the publishing process must follow a strict sequence. I implemented this using GitHub Actions:
Core Workflow
- Build and Deploy: Code is pushed to
main, built by GitHub Actions, and deployed to Cloudflare Pages. - Deployment Verification: A script polls the new article URL. It waits until the page returns HTTP 200 and contains valid
og:titleandog:imagetags. - Auto-Post: Once verified, the script calls the Bluesky API to create a post, manually constructing an
externalembed object with a thumbnail to ensure a high-quality link card. - Update Mapping: The script retrieves the post
uriandurlfrom the API and saves them tosrc/data/bluesky-comments.json. - Second Deployment: The Action commits the JSON change. This triggers a second deployment (which skips the post step because of the existing record), making the comment ID available on the production site.
Guardrails
- Bot Identification: GitHub Action commits use a specific
[bot]tag, which the script recognizes to only deploy and skip post-automation, preventing loops. - Idempotency: The script checks the mapping JSON before posting; existing articles are skipped to avoid duplicate posts.
Comment Embedding
Data Fetching
Instead of Server-Side Rendering (SSR), comments are loaded via client-side JavaScript to keep the site performance-friendly:
- Locate Resources: The component reads the global mapping JSON to find the Bluesky post
urifor the current page. - API Call: It uses the browser
fetchto request the public BlueskygetPostThreadendpoint. - Data Transformation: The raw thread is flattened to extract avatars, author names, content, and engagement counts (likes/reposts).
Rendering Strategy
- Depth Control: Only two levels of replies are rendered on the blog to keep the layout clean.
- Visual Consistency: The comment section matches the blog’s native typography and style.
Why This Solution?
- Simple and Sufficient: No need to maintain a separate database. Bluesky’s free API provides everything needed (unlike X, which has become heavily restricted).
- Static-Friendly: The blog remains a static site hosted on Cloudflare Pages, with dynamic content being pulled only when needed.
Comments
Read replies from Bluesky here.