Skip to main content

Blog Aggregation Support for Projects

This document provides a self-contained prompt template for adding blog aggregation support to other projects' CLAUDE.md files. When a project is added to the amiable.dev portfolio, its blog posts can be automatically aggregated to the main site.

How Blog Aggregation Works

The amiable.dev documentation site automatically aggregates blog posts from all projects listed in projects.json:

  1. Build-time fetching: scripts/fetch-blog-posts.js runs during prebuild
  2. Discovery: Uses GitHub Git Trees API to find markdown files in blog/ directory
  3. Content transformation: Front matter is enriched with source metadata, slugs are namespaced, and relative links are rewritten
  4. Output: Blog posts are written to blog/projects/{repo-name}/ with format: md to avoid MDX parsing issues

See ADR-004: Remote Blog Post Aggregation for the full specification.

Prompt Template for Other Projects

Copy and customize this section for your project's CLAUDE.md file:


Blog Post Guidelines (for amiable.dev aggregation)

Blog posts in this repository are aggregated to amiable.dev for the portfolio site. Follow these guidelines for proper aggregation.

Directory Structure

blog/
├── 2025-01-15-my-post-title/
│ ├── index.md
│ └── hero-image.png
└── 2025-01-20-another-post.md

Both directory-based posts (blog/YYYY-MM-DD-slug/index.md) and flat files (blog/YYYY-MM-DD-slug.md) are supported.

Required Front Matter

---
title: "Your Post Title"
description: "1-2 sentence description for SEO and social previews"
authors: [your-username]
tags: [relevant, tags]
---

The aggregator will:

  • Generate a namespaced slug: /blog/{repo-name}/{post-slug}
  • Add source_repo, source_url, and source_commit metadata
  • Merge project skills into tags
  • Inject default author from project config if not specified

Optional Front Matter

---
sidebar_label: "Short Sidebar Name" # Preserved if present
sidebar_title: "Alternative Title" # Alias for sidebar_label (takes precedence)
image: ./hero-image.png # Hero/social image
category: "tutorial" # Content categorization
series: "Getting Started" # Multi-part series name
featured: true # Highlight on portfolio
reading_time_override: 10 # Override calculated reading time
draft: true # Excluded from aggregation
---

Date Extraction

Dates are extracted in this order:

  1. Front matter date field
  2. Filename prefix (e.g., 2025-01-15-post-title.md)
  3. Falls back to current date with a warning

AI-Assisted Content

For posts with significant AI assistance, include:

---
ai_generated: true
ai_models:
- name: "Claude Opus 4.5"
version: "20251101"
tasks: ["content", "code", "research"]
confidence_score: 0.95
ai_tools:
- name: "Anthropic Messages API"
version: "2024-03"
ai_review_process: "Human reviewed and edited"
ai_quality_metrics:
accuracy: 0.95
coherence: 0.98
technical_depth: 0.92
---

Truncate Marker

Use <!--truncate--> (no spaces) to mark where the homepage excerpt ends:

Introduction paragraph visible on blog index...

<!--truncate-->

Full post content continues here...

The aggregator automatically rewrites:

  • Relative images: ./diagram.png → absolute GitHub raw URL
  • Relative doc links: ./README.md → absolute GitHub blob URL
  • ADR references: /docs/adrs/ADR-001-*/docs/adrs/projects/{repo}/adr-001-*

Exclusion Patterns

These files are excluded from aggregation:

  • README.md files
  • Files starting with draft- or _
  • Index/landing pages at blog root (index.md, blog.md)

Per-Project Configuration

To customize aggregation behavior, add blogConfig in the portfolio's projects.json:

{
"repo": "owner/repo",
"blogConfig": {
"enabled": true,
"directory": "blog",
"excludePatterns": ["/wip-/i"]
}
}

What Gets Transformed

Source FieldTransformation
titlePreserved as-is
descriptionPreserved as-is
authorsPreserved, or injected from project config
tagsMerged with project skills and repo name
dateExtracted from front matter or filename
sidebar_labelUses sidebar_title or sidebar_label if present, otherwise generates {project}: {title}
imagePreserved as-is
All linksRewritten to absolute URLs
JSX patternsEscaped to prevent MDX parsing errors

Cache Invalidation

The aggregator caches by commit SHA. To force re-fetch:

  1. Make any change to the source repository
  2. Or delete .cache/blog/manifest.json in the portfolio site
  3. Script version changes also invalidate cache (currently v1.1.0)