Comparison & Selection10 min read

How to Choose a Headless CMS: An Evaluation Framework for Developers and Content Teams

Most headless CMS regrets start with a demo that never touched your real schema. Choose a headless CMS instead by running a scripted proof of concept.

Published November 13, 2026

Most headless CMS regrets start with a demo that never touched your real schema. Choose a headless CMS instead by running a scripted proof of concept. Put the schema in code, change it through a pull request, build one real page, and test preview, governance, and agent access with your own content. In Sanity, for example, schemas are TypeScript defineType definitions in your repository, and a GROQ projection like "authorName": author->name returns the exact shape a component needs in one round trip.

The failure usually shows up after launch. Renaming a field takes a support ticket. The product page needs several API calls and a mapping layer. Preview depends on an add-on nobody priced, and the AI integration can't see your business rules. By then your content lives on the platform, the frontend is built around its API, and switching means a rewrite.

This guide breaks the decision into nine criteria you test yourself, from requirements to AI and agent readiness. It includes proof-of-concept tasks, a comparison of Sanity, Contentful, Storyblok, and Strapi, and a checklist of red flags. The argument running through it is that structured content and schema-as-code decide how well every other criterion holds up.

What are the steps to evaluate a headless CMS?

Evaluate a headless CMS in nine steps, from written requirements to a costed proof of concept, so that every platform is judged on the same evidence and not on its best demo. The order matters because early answers limit later ones. A schema decision changes what preview, localization, and agents can do.

1. Requirements. List your channels, locales, editor headcount, release cadence, compliance obligations, and the integrations you need on day one.
2. Schema design. Model two or three real content types from your business, including references and rich text. Skip the sample blog post.
3. Editor experience. Have your own editors work in the editing interface with your schema, not the vendor's sample project.
4. Query APIs. Build one real page and count the round trips the frontend needs.
5. Preview. Measure how much frontend code it takes for an editor to see a draft in context.
6. Localization. Test field-level and document-level translation against your locale strategy.
7. Governance. Check roles, approvals, audit trails, and certifications.
8. Scale and cost model. Map seats, API requests, bandwidth, and asset volume to pricing at the size you expect to reach.
9. AI and agent readiness. Check whether automation and agents can reach structured content through APIs, under the same rules as people.

Give the proof of concept a fixed window, usually one or two sprints, and run the same script on every shortlisted platform. A shared script stops each vendor from being tested on whatever it demos best. Score each step on evidence you produced yourself, such as a pull request, a query, or a screen recording of an editor at work. On paper, nearly every headless CMS ticks the same feature boxes. The real differences show up in how much code, configuration, and workaround each step took.

How do you test schema flexibility and schema-as-code in a proof of concept?

To test schema flexibility, change the schema the way you will in production, through code review, and see what breaks. A schema that exists only in a vendor's web interface can feel flexible on day one and still be risky to change in year two, because you have no diff, no review, and no branch to test against.

Run three tasks on every candidate. First, add a field through a pull request and confirm a teammate can review it like any other code change. Second, rename a field that already holds content and write the migration. This shows how the platform separates schema from data. Third, generate types for the frontend and check that they stay in sync with both the schema and the queries that use it.

Platforms take different approaches here. Contentful sets up schemas in its web app or through its CLI and migration tooling, and the definitions live inside the platform. Storyblok defines components in its UI with JSON export, which suits teams that want marketers to shape page blocks. Strapi and Payload let you define content types in code inside a project you host.

In Sanity, the schema is TypeScript in your repository. You write it with defineType and defineField, and it's versioned with full history, so AI coding tools like Copilot and Cursor can propose schema changes just as they edit any other file. The Content Lake separates structure from storage, so the schema and the content can change on separate tracks. TypeGen then generates TypeScript types from the schema and from GROQ queries. A renamed field becomes a compile error, not a blank component in production. This is the Model your business pillar in practice: the schema describes your domain in your own terms.

When scoring, give the rename-and-migrate task the most weight. Adding fields is easy on every platform. Platforms diverge when you need to change your mind.

✨

Schema in code, content in the cloud

Sanity sums up the split this way: "Schema lives in code, content lives in the cloud. Change one without breaking the other." Test that claim directly in the proof of concept. Rename a field in a branch, run the migration, and check what editors on the shared dataset see while it runs.

How should you evaluate the editor experience and preview?

Evaluate the editor experience by having the people who will publish every day build real content in each candidate, with your schema and a working preview, before engineering signs off. Editors who fight the interface route around it through spreadsheets, shared docs, and chat approvals. Then the structured content your developers designed never gets entered in a structured way.

Watch for three things during the session. Can editors find what they need without a developer configuring navigation for each team? Do custom fields, such as a product picker, a color swatch, or a pricing table, feel native or bolted on? Can an editor see a draft in the context of the real page, on the real frontend, before publishing?

The platforms differ here. In a 2026 third-party comparison of five platforms, Storyblok had the strongest out-of-the-box drag-and-drop visual editor, which matters for teams that build pages. Contentful offers side-by-side Live Preview, which the same comparison rated very good, and extends its hosted editor through apps. Strapi gives self-hosting teams an admin panel they can extend with plugins.

Sanity Studio works differently. It's a React application you configure in code and deploy, so custom input components, plugins, and Structure Builder layouts are part of your codebase. The App SDK lets teams build in-Studio apps for workflows the default interface doesn't cover. For preview, Visual Editing and the Presentation Tool let editors click from the rendered page into the field that produced it. The trade-off, noted in the same third-party review, is that the Presentation Tool needs implementation work in the frontend. Budget a frontend task for it in the proof of concept rather than assuming it arrives configured.

Score preview by the time it takes to get the first working click-to-edit on your own frontend, not on a starter template. That figure reflects what your team will actually maintain, and it's a better predictor of editor adoption than any feature list.

How do you compare query APIs for frontend developers?

To compare query APIs, build one real page on each platform, such as a product detail page with author, related items, and localized copy. Then count the requests and the post-processing code each one needs. The query layer decides how much glue code your frontend carries for the life of the project.

REST APIs return fixed resource shapes. A page with nested references often needs several calls, or an include parameter that returns more than you asked for. GraphQL lets the client select fields and follow relations in one request, which is why Contentful and Hygraph lead with it. GraphQL APIs usually enforce query complexity limits that cap how deep you can go. Strapi offers REST with populate parameters and a GraphQL plugin, and Storyblok's delivery API resolves relations by parameter. None of these approaches is wrong. Each puts the reshaping work in a different place.

GROQ is the query language for the Content Lake. One query can filter documents, follow references with the -> operator, and project the result into exactly the shape a component expects. A projection such as "authorName": author->name joins the author document and renames the field in the same request, so the frontend receives props rather than raw documents. Filters, ordering, slicing, and functions like match() and score() combine in the same expression. This is the Power anything pillar: one query layer gives a website, an app, and an agent the shape each needs.

In the proof of concept, write the same page query on each platform and keep the code. Compare the number of round trips, the lines of mapping code after the response, and whether you can generate types from the query itself. TypeGen covers that last step for GROQ. It produces result types from your queries, so the frontend breaks at build time when the shape changes.

Also check delivery: CDN caching, cache invalidation when content is edited, and whether real-time updates are available when the frontend needs fresh content without a rebuild. In Sanity, that's the Live Content API.

What governance and localization criteria should a headless CMS meet?

A headless CMS should meet governance criteria you can prove with an audit, and localization criteria you can prove with a real locale rollout. A settings screen proves neither. Governance failures surface late. A regulated page goes out without legal review, and nobody can reconstruct who approved it.

For governance, test roles and permissions at the field and document level, approval steps before publishing, scheduled and grouped releases, and an audit trail you can query. Ask for each vendor's certifications and sub-processor list early, because security review often takes longer than the technical evaluation. Contentful, for example, publishes its ISO 27001 certification, and a 2026 third-party comparison of five platforms rated its permissions and multi-space reuse the strongest. With Strapi's self-hosted model, compliance follows your own infrastructure, which some regulated teams prefer.

For localization, decide whether you translate at the field level (one document, many locale values) or the document level (one document per locale). Then test a fallback chain, a partially translated page, and a translation vendor integration. The same 2026 comparison rated Contentful's localization among the best of the platforms it reviewed.

In Sanity, governance follows the same code-first pattern as the schema. Workflows, currently in beta, are defined in TypeScript and versioned and deployed like the rest of your code, so the documented process can't drift from the one that actually runs. The process leaves its trail in the Content Lake rather than in a separate system, so audits become queries: "what published without legal review" is one GROQ query. Agents can take part too. An agent checks a submitted draft against your style guide and either moves it forward or sends it back. Content Releases group related changes so they go live together. In Sanity, your locale strategy is expressed in the schema, so test both the field-level and document-level patterns in code during the proof of concept.

â„šī¸

Compliance facts to collect before the contract

Ask every vendor for certifications, data residency options, and a sub-processor list before the proof of concept ends. For Sanity, the facts are SOC 2 Type II, GDPR compliance, regional hosting for data residency, and a published sub-processor list. Check each item against your own security questionnaire, since certifications differ from vendor to vendor.

How do you evaluate a headless CMS for AI and agent readiness?

To evaluate AI and agent readiness, check whether software, not just people, can find, change, and act on your content through APIs, under the same schema and governance rules. A text-generation button in the editor is the shallowest form of readiness. The deeper test is whether an agent can answer a request like "size L latex gloves, under $200 a pallet" exactly, across hundreds of thousands of records.

Three criteria separate platforms. The first is structured content. Typed fields and references give an agent a map of where to look, and with good schema hints even a small model does this well. The second is query access. Agents need filters and semantic ranking in one request, not a separate vector index that drifts out of sync. The third is event-driven automation. Something has to react when content is created, updated, or deleted, without a server you maintain.

This is where Sanity is built to be more than a headless CMS. It's an AI Content Operating System, the intelligent backend for companies building AI content operations at scale. In Sanity Context's GROQ mode, an agent queries the dataset at request time, with no build step and nothing to keep in sync. This requires a deployed schema (sanity schema deploy, Studio v5.1.0 or later). With dataset embeddings enabled, one GROQ query combines structured filters with semantic similarity. Functions are TypeScript or JavaScript handlers that run on Sanity's infrastructure. They react to create, update, and delete events, run on a cron schedule, or are called by other functions. They can read and write the dataset, traverse references, and call external services. A Blueprint file, sanity.blueprint.ts, sits in the repository and declares those functions. If something isn't in the blueprint, it isn't deployed.

Other platforms approach this differently. Contentful markets AI Actions inside its editor, Payload ships an MCP plugin in beta, and you can connect any platform with a delivery API to an external vector store. Score each option by how much sync code that connection needs and whether agents work under the same permissions as editors.

Semantic search ranks, it does not filter

In GROQ, text::semanticSimilarity() is only valid as an argument to score(). Semantic search ranks results. It doesn't filter them. Narrow the candidate set with a structured filter first, then rank what's left. That's why a well-typed schema still matters in an AI evaluation: the filter does the exact matching, and the embeddings handle what the filters can't express.

How do you build a scale and cost model for a headless CMS?

Build the cost model for a headless CMS from your own usage projections. Map seats, API requests, CDN requests, bandwidth, and asset storage to each vendor's pricing at the size you expect to reach in two to three years, not the size you are today. Entry tiers are designed to make the first month cheap. The bill that matters arrives when traffic, locales, and editor headcount grow.

Differences in pricing structure can change the ranking. A third-party comparison of five platforms, with pricing read in October 2026, listed these entry points. Sanity had a free tier and a Growth plan at $15 per seat per month, plus overages per API request, CDN request, GB of bandwidth, and GB of assets. Contentful Lite started at $300 per month, and Storyblok Growth was $99 per month. Strapi was free to self-host, with Strapi Cloud from $35 per month, and Payload was free to self-host. Check every figure on the vendor's own pricing page before it goes into a spreadsheet, since plans change often.

Self-hosting isn't free. With Strapi or Payload, cost moves from a subscription line to infrastructure, upgrades, backups, security patching, and an on-call rotation. For some teams that trade is right, especially where compliance requires control over hosting. For others, the engineering hours cost more than any license saving.

Model three scenarios: your current state, expected growth, and a traffic spike such as a product launch. For each one, estimate requests per page view after caching. A query layer that returns a full page in one request makes fewer billable calls than one that needs several. Add the cost of preview infrastructure, any add-ons needed for features you scored in earlier steps, and the editor seats your workflow design implies.

Scale also means people. If a platform needs a developer for every new page type, workflow change, or integration, your headcount has to grow along with your output. Automation that runs on the platform belongs in the cost model too. Sanity Functions, which react to content events, are one example: they replace glue services you would otherwise host and maintain.

What should a headless CMS evaluation checklist include, and what are the red flags?

A headless CMS evaluation checklist should confirm that you tested each of the nine criteria with your own content, your own frontend, and your own editors. The red flags are the gaps that surface when you try. Use the checklist as the final gate before signing a contract, not as a vendor questionnaire.

Checklist:
- The schema lives in a repository and changes through pull requests.
- A field rename and its migration completed without blocking editors.
- The test page loaded in a known number of requests, with generated types.
- Editors built real content and previewed it on your frontend.
- Localization fallbacks behaved as designed.
- Roles, approvals, and an audit trail were demonstrated.
- Security reviewed the certifications and sub-processor list.
- The cost model covers three growth scenarios.
- An automation hook fired on create, update, and delete.
- An agent or script queried structured content with filters, under the same permissions as people.

Red flags:
- The schema exists only in a vendor UI, with nothing in your repository.
- Preview needs a separate add-on that isn't in the quote.
- Seat-based pricing doesn't match your editor headcount.
- There's no event-driven automation hook, so every integration needs a polling service.
- AI is bolted on and can't see the schema or business rules.
- The vendor presents announced or beta AI features as shipped. Ask for status labels in writing.
- Nobody can show who published what, and when.

Treat a single red flag as a negotiation point and three as a reason to drop the vendor. The point of the framework isn't to find a platform with no trade-offs, because every option has some, Sanity included. Sanity's Presentation Tool needs frontend work, for example, and Storyblok's visual editor is stronger out of the box. The point is to choose your trade-offs deliberately, based on evidence from your own proof of concept.

Ready to try Sanity?

See how Sanity can transform your enterprise content operations.