Skip to content

Build federated blog example and tutorial (Astro + Bun) #691

@dahlia

Description

@dahlia

Sub-issue of #99. Deliver the federated blog scenario as a paired example repository and fedify.dev tutorial, as set in #99 (comment).

Scenario

A single-author federated blog where posts are authored as Markdown/MDX files checked into the repository. Astro builds each post to a static HTML page at build time, while a small set of server routes (the ActivityPub actor, inbox, outbox, and collection endpoints) run in Astro's hybrid SSR mode. This is the workflow most static-blog users already know: git commitgit push → deploy. Federation is a side effect of deploy.

Remote fediverse users can follow the blog and receive new posts in their inboxes; readers from other servers can comment via Note with inReplyTo, and comments are rendered under the post page.

Kept deliberately single-author to distinguish it from the social network example (sibling sub-issue), which is explicitly multi-user.

Stack

  • Framework: Astro (hybrid output: static by default, server routes for ActivityPub)
  • Content: Astro content collections, Markdown/MDX in src/content/posts/
  • Integration package: @fedify/astro
  • Runtime: Bun
  • Storage: bun:sqlite (Bun's built-in SQLite), no ORM
  • Database: SQLite (for followers, comments, queue state, and actor key pair)

Feature checklist

  • Blog content lives in src/content/posts/*.md (or .mdx). Each post renders to a static HTML page with a stable canonical URL.
  • Actor (Person or Service): WebFinger, persisted key pair (generated once, never regenerated on restart), followers collection.
  • Publishing on deploy: for each post in src/content/posts/, compare the current state against SQLite and emit the appropriate activity: Create(Article) for new posts, Update(Article) for edited posts, Delete(Article) (with Tombstone) for removed posts. Idempotent against re-deploys.
  • Comments: inbox handlers for Create(Note), Update(Note), and Delete(Note) whose inReplyTo matches a post's canonical URL. Stored in SQLite and rendered under the corresponding post.
  • Follow/Undo: inbox handler for Follow (auto-accept) and Undo(Follow).

Deliverables

  1. Create fedify-dev/astro-blog under the fedify-dev org. Full runnable Astro app implementing the feature checklist above.
  2. Write docs/tutorial/blog.md on fedify.dev as a step-by-step walkthrough of building the example from scratch. The tutorial should cover Astro's hybrid output mode, setting up the content collection, wiring Fedify into server routes, and the publishing-on-deploy pattern.
  3. Add the new tutorial to TUTORIAL.items in docs/.vitepress/config.mts (shows up in both top nav and sidebar).
  4. README of fedify-dev/astro-blog links back to the tutorial.
  5. Tutorial cross-links the Bun and Astro sections of the Deployment docs (Best practices for production deployments #689) for running the example in production.
  6. Add an entry to CHANGES.md.

Out of scope

Metadata

Metadata

Assignees

Labels

Type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions