Skip to main content

ADR-004: Remote Blog Post Aggregation

· 2 min read
Chris
Amiable Dev

We now aggregate blog posts from all projects at build time, just like we do with ADRs. This lets Docusaurus build a unified blog from distributed sources.

Prerequisites

  • Node.js >= 18
  • GITHUB_TOKEN env var (optional, but recommended for higher API rate limits)

Problem

We had blog posts scattered across multiple project repos. No central place to discover them.

Solution

Extended the ADR aggregation pattern:

projects.json → fetch-blog-posts.js → blog/projects/{repo}/

Key Decisions

  1. Reuse lib/ modules - Extracted shared code from fetch-adrs.js:

    • lib/frontMatter.js - YAML parsing, JSX escaping
    • lib/cacheManifest.js - SHA-based cache invalidation
    • lib/rewriteLinks.js - Image/doc link rewriting
    • lib/githubFetch.js - Retry logic, Octokit wrapper
  2. Inline author injection - If a post has no author, inject project name/URL

  3. Date extraction - Parse YYYY-MM-DD from filenames as fallback

  4. Tag namespacing - All posts tagged with repo name for filtering

Usage

# Fetch blog posts from all projects
npm run fetch-blog-posts

# Or just run the full prebuild
npm run prebuild

Source Contract

The script expects blog posts in the remote repo's blog/ directory (configurable):

  • Markdown files (.md) are discovered
  • Files starting with draft- or _ are excluded
  • README.md is ignored
  • Dates parsed from YYYY-MM-DD-slug.md filename format

Configuration

Add your project to projects.json:

{
"repo": "owner/repo",
"title": "My Project",
"skills": ["TypeScript"],
"blogConfig": {
"enabled": true,
"directory": "blog",
"excludePatterns": ["/wip-/i"]
}
}

Images in posts are rewritten to absolute GitHub URLs. No local downloads.

Test Coverage

  • 69 lib/ tests
  • 23 fetch-blog-posts tests
  • 29 blog schema tests
  • 286 total tests passing

Files Changed

lib/frontMatter.js        # Extracted from fetch-adrs.js
lib/cacheManifest.js # Extracted from fetch-adrs.js
lib/rewriteLinks.js # Extracted from fetch-adrs.js
lib/githubFetch.js # Extracted from fetch-adrs.js
src/data/blog-schemas.ts # Zod validation
scripts/fetch-blog-posts.js # Main script
src/components/Projects/ProjectCard.tsx # Blog badge

See Also