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_TOKENenv 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
-
Reuse lib/ modules - Extracted shared code from fetch-adrs.js:
lib/frontMatter.js- YAML parsing, JSX escapinglib/cacheManifest.js- SHA-based cache invalidationlib/rewriteLinks.js- Image/doc link rewritinglib/githubFetch.js- Retry logic, Octokit wrapper
-
Inline author injection - If a post has no author, inject project name/URL
-
Date extraction - Parse
YYYY-MM-DDfrom filenames as fallback -
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.mdis ignored- Dates parsed from
YYYY-MM-DD-slug.mdfilename 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
- ADR-004 - Full decision record
- GitHub - CLAUDE.md - Updated project docs
