Channel Sites
Publishing platform for 13 independent content sites on a shared codebase and deployment pipeline.
Channel Sites is a monorepo for multiple publications. Each channel has its own domain and identity, but shares the same Astro framework, package set, and Cloudflare integrations.
Architecture
How it's wired.
How It's Built
Implementation notes.
Monorepo with shared packages
pnpm monorepo with shared packages: channel-kit (UI/templates), config, seo, media, search, store, and analytics.
Thin channel wrappers
Each channel is mostly one site.config.ts: name, domain, theme, categories, social links, store/newsletter settings, search, and analytics tokens.
Git-versioned content
Articles live as markdown under data/{channel}/articles/{category}/. sync:content copies them into Astro collections before build. Content stays versioned and reviewable in Git.
Publishing API for Orchestrator
Each site exposes POST /api/publish for article artifacts with Bearer auth, creating a GitHub PR. Publishing mode can be pr_required, auto_merge, or manual_only.
Semantic search with AI Search
Cloudflare AI Search runs per channel with normalized queries, per-IP rate limits (30/min), and ranked results. Keyword fallback is used in local dev.
SEO as infrastructure
Shared SEO package generates JSON-LD, category sitemaps, RSS feeds, robots.txt, canonicals, and OpenGraph tags from channel config.
Primitives Used
Cloudflare primitives in this project.
Why This Design
Why I built it this way.
"This project shows how to scale a content network without copying stacks per site. Most variation is config-level, while infrastructure, deployment, and platform integrations stay shared and predictable."