CMS Chronicle #03: Tags and Discovery Cross-Collection Discovery
We added tags to every article this week. Click one and you get a list. The infrastructure was already there — it just needed a front door.
The question came up naturally while looking at the finished Articles section: what if a reader wants to find everything we've written about architecture, regardless of which series it lives in? Category pages solve vertical discovery — all the CMS Chronicle posts, all the AI Dispatch posts. But they don't help when a topic cuts across series.
Tags solve the horizontal.
What we shipped
- Tags display as teal pill chips at the bottom of every article
- Each chip links to
/tags/[tag]— a listing page showing all articles with that tag - The listing works for any count, including a single article
#taguses the inline code colour — teal text on a teal-tinted background, switching correctly between light and dark mode
The CMS core already had findByTag() from last session. This was purely routing and rendering — a new dynamic route, tag chips in the article layout, and tags added to the JSON for all three existing articles.
The colour decision
Inline code in articles (code blocks in Markdown) uses the same teal palette: #14B8A6 text on a 10% teal background in light mode, slightly brighter in dark mode. When we designed the tag chips, it made sense to match — same family, same meaning. Teal means navigable in this UI.
Cross-collection by default
getPostsByTag() calls findByTag(tag, ['posts']) under the hood. Right now all content is in the posts collection, so the distinction doesn't matter. But when we add case studies, docs, or other collections, tag pages will surface them automatically. The architecture was built for that from day one.
“The infrastructure was already there. It just needed a front door.”
What's next
Three articles in, the blog is starting to feel like something. The next large milestone is Phase 3 — getting @webhouse/cms off the filesystem and onto a real database. Supabase adapter, PostgreSQL, Docker, Fly.io deploy. When that lands, the CMS stops being a local tool and becomes something anyone can run.