Skip to main content
architecture

ADR-004: Remote Blog Post Aggregation

2 min read

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:

code
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​

bash
# 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:

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​

code
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​