A headless CMS is a content management system that stores and organizes content behind an API, usually REST or GraphQL, and renders no pages itself. A separate front end, such as a website, a mobile app or a kiosk, fetches that content and decides how it looks, so one content hub can feed every channel at once.
This guide is for the marketing or product owner and their developer deciding whether to move a site to a headless CMS: how it differs from a traditional CMS, how it works from publish click to page view, the options as of October 2026, the SEO and cost trade-offs, a decision checklist and a migration plan. For the wider picture of how websites get built and launched, see our web development guide.
What a headless CMS actually is
The cleanest definition comes from AWS: a headless CMS is "a content repository that allows you to deliver content to any frontend or user interface", where a traditional CMS "couples the creation, storage, and presentation layers into a single system". The head being removed is the website itself: the theme, the templates, the page rendering. What remains is the body: the admin where editors work, the repository where entries live, and an API that answers queries with JSON.
A standard WordPress install is the classic coupled system: Contentful lists it among the monolithic CMSes that tightly couple the frontend with the backend, so content, admin and the PHP theme that renders the pages run as one program. A decoupled CMS splits the two but keeps a presentation layer: AWS describes a blend that still includes one while using APIs to push content to other channels, and Strapi's guide defines a hybrid CMS as the same blend, with API delivery plus a built-in presentation layer and WYSIWYG editing. As Contentful puts it, "a decoupled CMS comes with a head, but using it is completely optional". A purely headless CMS ships no presentation layer at all: until you build a front end, the content reaches no one.

| Traditional (coupled) | Decoupled or hybrid | Headless | |
|---|---|---|---|
| Who renders the pages | The CMS theme, on the same server | The CMS for its own site; APIs feed the other channels | A separate front end you build |
| Preview for editors | Built in | Built in for the CMS-rendered site | Must be wired up (draft mode, or a visual editor add-on) |
| Editor experience | WYSIWYG page building | Page building on the built-in site | Structured entries edited in forms, unless the platform adds a visual editor |
| Performance | Pages rendered per request, usually behind a page cache | Same for its own site; other channels depend on their own front ends | Your choice per route; static pages are served from a CDN |
| Security surface | Admin, theme and plugins share the public web server | Same for the built-in site, plus the API | The public site and the CMS are separate programs; the CMS API and its tokens are what you protect |
| Cost shape | One system to host and patch | One system, plus some glue code | Two systems to run, plus a build pipeline |
The reason teams accept the split is reuse. AWS lists the typical use cases: one entry feeding a website and a mobile app, multilingual content managed once, product catalogs for e-commerce, and delivery to chatbots, signage and other non-web channels. Contentful calls the habit COPE, "Create Once, Publish Everywhere": with structured entries in one hub, you edit once and the update applies everywhere the entry appears, instead of someone copying text between a web page and an app screen.

How a headless website works, end to end
Whatever the products involved, every headless build runs the same loop. The code in this guide uses Next.js; Nuxt, SvelteKit and Astro fill the same role.
- Model the content. Developers define content types and fields.
- Editors write in the CMS. Entries are stored as structured data, with roles, versioning and often scheduled publishing, depending on the platform and plan.
- The front end fetches entries through the API.
- Each route picks its rendering mode: static, incremental or per-request server rendering.
- A CDN serves the result, so most visits never touch the CMS or the front-end server.
- Editors preview drafts through a cache bypass on the front end.
- Publishing fires a webhook that revalidates only the pages that changed.
The API: REST, GraphQL or the vendor's own query language
A REST API exposes one URL per kind of resource and returns the JSON shape the server defines, which is simple to call and simple to cache. GraphQL instead lets the front end specify exactly the fields it wants, and the server responds with just those. Here is WPGraphQL's own tutorial example, fetching one post by its database id:
query GetPostById($id: ID!) {
post(id: $id, idType: DATABASE_ID) {
id
title
date
}
}
Sanity takes a third path with GROQ, its own query language, which filters documents and then projects the exact fields to return. This is the example from Sanity's documentation:
*[_type == 'movie' && releaseYear >= 1979]{ _id, title, releaseYear }
The buyer's takeaway: all three speak JSON over HTTP, so the front end can be anything that makes requests; the query language is a developer-experience choice, not a capability gap. If your organization is standardizing on API-first design beyond the website, that broader shift is covered in our post on enterprise API development.
Rendering: a choice per route, not per site
A headless front end chooses how each route renders. Pages that can be pre-built use static generation (SSG): they are rendered at build time and served as files from a CDN. Pages that change when an editor publishes use incremental static regeneration (ISR), which Next.js documents as a way to update static content without rebuilding the entire site: the cached page keeps being served while a new version generates in the background. Pages that must be personal, such as an account area, render on the server per request. The front end often deploys to a serverless platform, which brings its own scaling and cost model; how serverless computing works is the companion read.
Preview: the feature you must rebuild
The classic headless complaint is losing the preview button. The fix is a draft mode: the CMS opens a URL on the front end with a shared secret, the front end sets a cookie, and that editor's requests skip every cache and fetch the draft directly while other visitors keep the cached page. Next.js documents exactly this contract for a headless CMS: its Draft Mode sets a __prerender_bypass cookie and serves the editor's pages with Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate, fetching from the CMS each time. The same guide gives two rules for the entry URL: check the shared secret before enabling Draft Mode, and redirect to the path of the entry you fetched from the CMS, not to a value from the query string, which avoids an open redirect. The names are Next.js-specific, but any front end needs the same three parts (a secret-protected URL, a cookie, a cache bypass), and none of it exists until someone wires it up.
Publishing: webhooks and revalidation
When an editor hits publish, the CMS fires a webhook: an HTTP POST to a URL on the front end. What a webhook is and how to secure one is its own subject; here, the endpoint validates a shared secret and then revalidates the pages that show the changed entry. In Next.js 16, that is a Route Handler calling revalidateTag:
// app/api/revalidate/route.ts: the URL the CMS webhook calls on publish
import { timingSafeEqual } from "node:crypto";
import { revalidateTag } from "next/cache";
function secretMatches(given: string | null, expected: string): boolean {
const a = Buffer.from(given ?? "");
const b = Buffer.from(expected);
// timingSafeEqual throws if the lengths differ, so check them first.
return a.length === b.length && timingSafeEqual(a, b);
}
export async function POST(request: Request) {
const expected = process.env.CMS_WEBHOOK_SECRET;
if (!expected) return new Response(null, { status: 500 }); // fail closed
if (!secretMatches(request.headers.get("x-webhook-secret"), expected)) {
return new Response("Invalid secret", { status: 401 });
}
revalidateTag("posts", "max");
return new Response("Revalidated");
}
The comparison is constant-time because crypto.timingSafeEqual is documented as suitable for comparing secret values, and a missing secret fails closed. If your CMS signs the request body instead of sending a custom header, verify the HMAC as the webhook guide describes.
Pages opt into the tag when they fetch: fetch(url, { next: { tags: ["posts"] } }). With the recommended max profile, revalidateTag marks the tag as stale and the next request triggers the refresh in the background, so no reader waits on a rebuild (Next.js revalidateTag reference). The trade-off is that the next visitor still gets the old page while the new one builds; for a correction that must show at once, the same reference offers { expire: 0 }, which never serves stale content, so the next request waits for the fresh page. Rebuilding the whole site on every publish, the older pattern, scales with the size of the archive; tag-based revalidation refreshes only the pages that use the changed tag.

Model the content, not the pages
A traditional CMS stores pages; a headless CMS stores things. AWS describes the practice: instead of template layouts for pages, teams "define content types using text, media, metadata, and relationships". Contentful's term for the raw material is structured content: content "broken down into small building blocks, organized in a predictable way, and classified with metadata". A content model for a blog might look like this:
# One content type, defined as fields, not as a page
Article:
title: text (required)
slug: text (unique)
publishedAt: date
author: reference to Author
body: structured blocks
topics: list of references to Topic
References are the point. The author is an entry, not a string, so a bio corrected once updates on every article, author page and RSS feed that uses it. The same applies to products, office locations, alerts and anything else that appears in more than one place.
One field decides how portable your content is: the body. Stored as an HTML string, body text renders on the web and nowhere else cleanly. Stored as structured blocks, it renders anywhere. The open Portable Text specification, which Sanity lists as a feature of every plan, shows the second approach: "an open specification for structured block content", kept as JSON and "renderable anywhere". Structured blocks also let editors embed real components, such as a chart or a call to action, inside body text without pasting HTML, because the front end decides how each block type renders.
Two more modelling questions to settle before choosing a platform:
- Localization. AWS notes that headless systems treat language variants as structured metadata rather than duplicated sites. Check how each candidate stores translations: a field per locale, or an entry per locale with fallback rules.
- Governance. Roles, approval workflows, versioning and scheduled publishing differ by platform and often by plan. Verify them in a trial with your real editorial process before signing anything.
Tip
If a teaser, price or bio will appear in two places, make it a content type with a reference, not a paragraph typed twice. Pages become compositions of entries.
The headless CMS options as of October 2026
No ranking here, just the map, grouped by hosting model and licence, with facts checked against each vendor's own pages in October 2026. Most headless platforms are hosted services. As Sanity's headless guide puts it, "today most headless CMSes operate as a Software as a Service (SaaS) company, providing a managed backend and hosted web application".
Hosted SaaS platforms
| Platform | Content API | What stands out |
|---|---|---|
| Contentful | REST and GraphQL | Its APIs also manage content modelling, user roles and webhooks programmatically |
| Sanity | GROQ and GraphQL | The editor, Sanity Studio, is React-based and customizable, and its code is under an MIT licence |
| Storyblok | REST and GraphQL | A Visual Editor that shows a draft preview of your own website beside the content form |
| Hygraph | GraphQL, described as GraphQL-native | Formerly GraphCMS; Content Federation brings content from other systems into the Hygraph API without migrating it |
| Contentstack | API-first, cloud-based | Content Cloud, its headless CMS, is one product in the Agentic Experience Platform, alongside Data Cloud and personalization |
| Prismic | Content API, JSON over HTTP | Slices: reusable page sections that developers define in code and marketers assemble visually |
Sanity's content lives in Content Lake, which its pricing page lists as a hosted, real-time content database.
On cost, each of the six lists a free plan on its pricing page (Contentful, Sanity, Storyblok, Hygraph, Contentstack and Prismic, all checked in October 2026). The vendors pitch those plans at learning, individuals, personal projects or proofs of concept, so budget a business site for a paid plan. Plans differ in limits such as seats, locales, API calls and bandwidth, and in features: Contentful lists scheduled publishing from its Lite plan upward, and Sanity lists scheduled drafts from Growth, not on Free.
Open source you host yourself
| Platform | Licence, as of October 2026 | Runs where |
|---|---|---|
| Strapi | MIT for the community edition; enterprise features under ee/ use a commercial licence | Self-hosted, or the vendor's Strapi Cloud |
| Directus | Monospace Sustainable Core License 1.0: any purpose except a competing use of the software; each version also becomes available under GPL-3.0 on its fourth anniversary | Self-hosted, or Directus Cloud |
| Payload | MIT | Self-hosted; its README lists one-click deploys to Vercel and Cloudflare |
Strapi calls itself an "open-source, self-hosted headless CMS" written in JavaScript/TypeScript. Directus takes a database-first angle: connect a SQL database and it generates production-ready REST and GraphQL APIs automatically, so it doubles as an API layer over data you already have. Read its terms before treating it as free: per its licensing docs, self-hosted instances without a licence key run on a core tier, and its pricing page limits that tier to 3 user seats and 25 collections. Organizations under $5M in annual revenue and fewer than 50 employees can apply for its Open Innovation Grant, which gives full access to self-host at no software cost. Payload is an open-source headless CMS and application framework that, per its README, installs directly in your existing Next.js /app folder; in June 2025 the Payload team joined Figma, which said Payload will remain an open-source product.
Self-hosting is not free hosting. You own updates, backups, the database and the admin's uptime: the workload a SaaS subscription buys away. For a marketing site, weigh that operational bill against the subscription, not just the licence fee.
WordPress and Drupal, used headlessly
WordPress and Drupal can also run headless, which matters if your organization already lives in one of them.
WordPress added REST API content endpoints to core in version 4.7 (released December 6, 2016): posts, comments, terms, users, meta and settings became available as JSON. The REST API handbook notes the API is now "the foundation of the WordPress Block Editor" and can "bring your WordPress content into completely separate applications". For GraphQL there is WPGraphQL, a free, open-source plugin that adds a GraphQL schema and API to any WordPress site. In October 2024 its creator Jason Bahl announced it would become a canonical community plugin on WordPress.org as he moved to Automattic, and as of October 2026 the plugin's directory page still describes it as becoming one.
Headless WordPress keeps the admin, the media library and the editor your team already knows. The front end becomes a separate application, and any plugin that assumes it renders the site, such as an SEO plugin printing meta tags into the theme, needs its output fetched and rendered by your front end instead. For what those plugins do on a conventional install, see our WordPress SEO guide.
"Next.js vs WordPress" compares different layers. Next.js is a React framework for building full-stack web applications; WordPress is a content management system that also renders the site. The real choices are WordPress end to end, WordPress as the back end behind a Next.js front end, or Next.js in front of another CMS from this guide. Our own decision table follows that split: WordPress fits when editors publish every day and rely on plugins they already know, and Next.js with a headless CMS fits when structured content is reused across pages, channels or languages.
Drupal's equivalent is JSON:API, which joined Drupal core in 8.7.0 on May 1, 2019. The release notes flag one design decision worth copying: the core JSON:API module runs read-only by default for security, so writes stay off until you deliberately enable them.
Git-based CMSs
A fourth model skips the database and the API server entirely: the CMS is an editing layer over files in your Git repository. Decap CMS, formerly Netlify CMS, is open source under the MIT licence and works with any static site generator. TinaCMS is open source under Apache 2.0, stores content as Markdown in your Git repo and adds a visual editor on top. Publishing is a commit; the site rebuilds from Git. The model fits documentation, blogs and smaller marketing sites whose teams already work in Git. Because Git stores files rather than relations, heavy cross-referencing between entries and large media libraries are where this model is most likely to strain.
Where Jamstack fits in 2026
Jamstack is the term you will meet next to every headless CMS, so it helps to know what it named. Jamstack.org says the name came about because Matt Biilmann and Chris Bach, building modern web workflows at Netlify, had no easy way to refer to the architecture in conversation; Netlify's own retrospective dates the coining to 2015. Biilmann presented the idea at SmashingConf San Francisco in 2016 in a talk titled "The New Front-end Stack. Javascript, APIs and Markup", the three parts that the original spelling, JAMstack, abbreviates: pre-render the markup, serve it from a CDN, and add dynamic behaviour with JavaScript calling APIs. A headless CMS was a common API behind it.
The definition has since moved. Netlify's 2022 version calls Jamstack "an architectural approach that decouples the web experience layer from data and business logic", and Jamstack.org still names two principles, pre-rendering and decoupling. In 2021 Biilmann wrote that hybrid frameworks such as Next.js, Nuxt and SvelteKit, which mix pages pre-rendered at build time with routes rendered by serverless functions, were gaining real momentum, and that pre-rendering a larger website may mean waiting several minutes on every deployment. That is the per-route rendering choice described above. Neither half requires the other: a Jamstack site can read Markdown from Git with no CMS at all, and a headless CMS can feed a fully server-rendered application.
SEO and performance on a headless stack
A headless build moves everything search engines see into the front end: the HTML, the title and meta description, structured data, canonical tags, the XML sitemap and the redirect map. In a coupled CMS the theme and plugins print these; in a headless stack your developers own them. That is more work, and it is also the appeal: nothing between your markup and the crawler.
The rule that matters most for search: render content pages on the server or at build time. Google's JavaScript SEO documentation explains that Googlebot queues pages for a separate rendering pass that "can take longer" than the initial crawl, and advises that "server-side or pre-rendering is still a great idea because it makes your website faster for users and crawlers, and not all bots can run JavaScript". A client-only front end waits in that rendering queue before its content is seen, and crawlers that never run JavaScript see an empty shell. Rendering choices also shape technical SEO audits, which is where a headless migration should start.
Performance follows the same logic. Static pages served from a CDN start fast almost by default; the discipline you keep is the JavaScript budget, because a heavy client-rendered front end can still fail on real phones. Google's guidance is to judge Core Web Vitals at the 75th percentile of page loads, segmented across mobile and desktop: LCP within 2.5 seconds, INP of 200 milliseconds or less and CLS of 0.1 or less. Our Core Web Vitals guide covers how to measure and fix each one.
Finally, URLs. A headless rebuild that changes your URL structure without redirects throws away the rankings the old URLs earned. Keep every URL identical where you can, and 301 the rest. The full process is in our website migration SEO guide.
When a headless CMS is the wrong choice
Headless is a means, not a status symbol. Stay coupled, or choose a hybrid, when any of these describe you:
- The site is a small brochure site whose pages change a few times a year. A coupled CMS, or a static site with a Git-based CMS, is simpler and cheaper to run.
- Editors build pages visually every day. If marketing assembles landing pages from mixed sections without a developer, a form-based CMS will feel like a downgrade unless you pick one with a real visual editor, or invest in preview and a well-designed component library.
- No developer will own the front end after launch. The front end is a product: dependencies to update, deployments to watch, performance budgets to enforce. The role can be an agency, but it cannot be empty.
- The site depends on plugins that only exist in a coupled runtime. Membership portals, complex forms, multilingual plugins: each one becomes a build project on a headless stack. Price them before deciding.
- The budget only covers one system. Two platforms mean two bills, plus a build and preview pipeline to maintain, editor training and the migration itself; free tiers and free self-hosting do not remove the developer time.
A checklist to decide
Answer these six questions honestly, and the architecture usually picks itself:
| Question | If yes | If no |
|---|---|---|
| Will the same content appear in more than one channel? | Headless earns its keep | A coupled CMS is simpler |
| Do editors need visual page building most days? | Headless only with a visual editor, or stay coupled | Headless fits |
| Is someone committed to owning a front end for the life of the site? | Headless is viable | Stay coupled |
| Do key features come from plugins that render pages? | Budget to rebuild them as services, or stay coupled | Headless fits |
| Do speed and Core Web Vitals budgets matter commercially? | Headless with static rendering is the straightest path | Either can work |
| Will the team adopt structured content (things, not pages)? | Headless fits | Expect a painful migration |
How to migrate from a traditional CMS
A typical move from a coupled CMS to a headless one runs in this order:
- Inventory the content and the URLs. List every post type, taxonomy and media library, and every URL that earns traffic, from analytics and Search Console. The URL list becomes the redirect map.
- Export the content. WordPress's Tools, Export screen produces an XML file of posts, pages, comments, custom fields, terms and menus. It lists content types, not media files: the WordPress Importer plugin downloads attachments separately (an
import_allow_fetch_attachmentsfilter switches that off), so plan the media library as its own step. For a very large site, a scripted export through the CMS's own API may be easier to repeat than one XML file. - Map the model. Post types become content types, custom fields become fields, taxonomies become references. This is where the structured-content decisions land, so involve the editors, not only the developers.
- Rebuild the templates as front-end components, with metadata, structured data and sitemaps owned by the front end, and rendering chosen per route.
- Keep URL parity where possible and write 301 redirects for the rest, then test the whole map on staging before launch. Our website migration SEO guide details this step.
- Wire preview and train the editors. Draft preview, roles and the publish flow need a rehearsal, ideally one full publishing cycle with both systems running in parallel.
- Cut over, then watch. 404 reports, Search Console coverage and Core Web Vitals field data, daily for the first month.
If the checklist points at headless and you want one team for both halves: our web design and development service builds sites on Next.js with a headless CMS, or on WordPress when editors publish daily and rely on plugins they already know. The CMS work covers structured content models, draft previews and editorial roles, and Core Web Vitals budgets are enforced in the delivery pipeline. The engagement starts with a website audit, so the recommendation to refresh, rebuild or replatform rests on measured data.


