Channel Sites
A multi-channel publishing platform. 13 independent content sites sharing one infrastructure, one design system, and one deployment pipeline — all on Cloudflare Workers.
Channel Sites is a monorepo that powers a network of topical content publications. Each channel — WarFronts, HomeFronts, MegaProjects, and 10 others — gets its own domain, its own editorial identity, and its own Workers deployment. But they all share the same Astro 6 framework, component library, and Cloudflare primitive integrations.
How It's Built
Architecture and implementation.
Monorepo with shared packages
pnpm monorepo with channel-kit (UI + templates), config (schema + validation), seo (JSON-LD, sitemaps, RSS), media (Cloudflare Images + YouTube facade), search (AI Search + fallback), store (FourthWall), and analytics (typed event system).
Thin channel wrappers
Each channel is one site.config.ts defining: name, domain, tagline, theme, categories, YouTube channel ID, social links, store config, newsletter config, search instance, analytics tokens. One config, one complete site identity.
Git-versioned content
Articles live in data/{channel}/articles/{category}/ as markdown with frontmatter. Prebuild sync:content script copies to Astro Content Collections. Content is version-controlled, diffable, and reviewable through Git.
Publishing API for Orchestrator
Each site exposes POST /api/publish accepting article artifacts via REST, authenticated via Bearer token, creating a GitHub PR. Publishing mode configurable per channel: pr_required, auto_merge, or manual_only.
Semantic search with AI Search
Cloudflare AI Search binding per channel. Normalized queries, per-IP rate limiting (30/min), ranked results with title, description, URL, image, and relevance score. Keyword fallback for local dev.
SEO as infrastructure
Shared seo package generates: JSON-LD structured data (Article, Organization, SearchAction), per-category XML sitemaps, RSS feeds, robots.txt, canonical URLs, and OpenGraph tags. Configured by each channel config.
Architecture Map
Request flow and service topology
Git push → GitHub Actions → Build matrix (13 sites)
↓ per site
pnpm build → sync:content → Astro build → wrangler deploy
↓
Workers deployment (one per channel)
Reader → Workers (Astro SSR) → Article page
├── AI Search binding → Semantic search results
├── Analytics Engine → Route metrics
└── PostHog proxy → /ingest/* → eu.i.posthog.com
Orchestrator → POST /api/publish → GitHub PR → Merge → Rebuild → Live article
Newsletter signup → POST /api/newsletter → Customer.io API
Store → FourthWall API → Regional pricing → Cart / Checkout Primitives Used
Every Cloudflare binding in this project.
What Makes This Interesting
The architectural angle worth paying attention to.
Spinning up a new channel means creating a site.config.ts and a thin Astro wrapper. The shared packages handle the rest. GitHub Actions uses a matrix strategy — packages changes trigger all 13 sites, site-specific changes only trigger that site. The publishing API accepts articles from the Orchestrator pipeline, creating PRs for editorial review before anything goes live.