Technical
Headless CMS Basics: Decoupling Content from Presentation
A client's WordPress site was slow, their mobile app could not access the content, and their marketing team needed to publish to three different channels from one source. A headless CMS solved all three problems simultaneously.
What Is a Headless CMS
A traditional CMS like WordPress manages content AND renders the pages visitors see. A headless CMS manages content and exposes it through an API. The 'head' (the frontend that renders pages) is a separate application that consumes the API.
Traditional CMS:
Content -> Template Engine -> HTML Page (one output)
Headless CMS:
Content -> API -> Web frontend
-> Mobile app
-> Email newsletter
-> Any other consumerWhy Go Headless
Three scenarios where headless architecture wins:
- Multi-channel publishing: Same content appears on your website, mobile app, and email newsletter without duplicating anything
- Frontend freedom: Use React, Next.js, Vue, Svelte, or any other framework. You are not locked into PHP templates.
- Performance: Static site generation with API-driven content gives you instant page loads and perfect Lighthouse scores
Popular Headless CMS Options
| CMS | Type | Best For | |-----|------|----------| | Strapi | Self-hosted, open source | Full control, custom content types | | Contentful | Cloud, proprietary | Enterprise teams, managed infrastructure | | Sanity | Cloud, real-time | Collaborative editing, custom schemas | | WordPress + REST API | Hybrid | Migrating existing WordPress content | | Custom (FastAPI + DB) | DIY | Complete control, minimal dependencies |
My Approach: Custom Headless
For the PLAI blog platform, I built a custom headless CMS using FastAPI and DynamoDB:
# FastAPI backend serves content as JSON
@router.get('/posts')
async def list_posts(status: str = 'published'):
items = query_posts_by_status(status)
return [item_to_response(item) for item in items]// Next.js frontend fetches and renders the content
const res = await fetch('http://api.peaklight.ai/posts');
const posts = await res.json();Why custom? Because my requirements are simple (blog posts, categories, newsletters) and I do not need the complexity of Strapi's plugin system or the monthly cost of Contentful's cloud service.
When to Use a Headless CMS vs Traditional
Go headless when you need to serve content to multiple frontends or when you want full control over the rendering layer. Stick with traditional WordPress when you have one website and non-technical editors who need a familiar, well-documented admin interface.
The Content Pipeline Pattern
Headless CMS enables a clean content pipeline:
- Create content (admin UI, API calls, migration scripts)
- Store content (database or CMS backend)
- Deliver content (REST or GraphQL API)
- Render content (one or more frontend applications)
Each step is independent and replaceable. You can change the frontend framework without touching the CMS. You can add a mobile app without changing the API. That decoupling is the core value of going headless.
See the Strapi documentation for a popular open-source headless CMS option with excellent developer experience.
RELATED READING
The Consulting Shift I Am Making In Year Two
After a year of writing and building, my consulting practice is changing shape. Shorter engagements. Sharper outcomes.
ReadThe Frontend Shift: Shipping Less JavaScript In Year Two
A year ago I reached for Next.js for everything. This year I often reach for nothing.
ReadThe Serverless Lesson I Would Write On A Sticky Note
After a year of shipping serverless projects, one rule explains most of the wins and all of the losses.
Read