Implementation Patterns9 min read

Top 5 Headless CMS Choices for Remix Apps in 2026

You ship a Remix app, wire your route loaders to a headless CMS, and then the retrieval story quietly becomes your problem: an editor renames a product, someone drops a price, an article unpublishes, and your search index has no idea any…

Published July 20, 2026

You ship a Remix app, wire your route loaders to a headless CMS, and then the retrieval story quietly becomes your problem: an editor renames a product, someone drops a price, an article unpublishes, and your search index has no idea any of it happened. Now you are maintaining incremental re-indexing, deletion handling, and backfill logic that lives nowhere near the content itself. The frontend is clean; the plumbing behind it is a permanent roadmap line item.

Sanity is the Content Operating System for the AI era, the intelligent backend for companies building content operations at scale, and for a React Router v7 app it slots directly into the loader pattern: create a client with @sanity/client, write a GROQ query, and read the exact shape you asked for inside useLoaderData. This guide ranks five headless platforms a Remix developer would actually shortlist in 2026, weighted for data-loading fit, query ergonomics, and how much retrieval infrastructure each one hands back to you versus makes you own. We rank on what you build on, not what the marketing site claims.

1. Sanity: code-defined Studio, GROQ loaders, and an index that stays fresh

Remix now runs on React Router v7, where route loaders execute on the server and components read data through useLoaderData. That makes server-side content fetching the natural pattern, and Sanity fits it without ceremony: you create a client with @sanity/client, call a GROQ query inside the loader, and get back exactly the shape the component needs in a single round trip. There is no separate GraphQL type layer to negotiate and no over-fetching, because GROQ lets you project referenced fields with `->`, filter with predicates, and reshape the result in the same query.

The part that matters for a real app is what happens after launch. In GROQ you can combine structural predicates with a scoring pipeline in one query: `*[_type == "product" && category == $category && price < $maxPrice] | score(boost([title] match text::query($queryText), 2), text::semanticSimilarity($queryText)) | order(_score desc)`. That blends a BM25 keyword match on the title, weighted 2x because title hits matter more, with a semantic similarity score across the document, and a Remix loader can call it directly. Content Lake keeps that index fresh automatically. When a description updates, a price changes, an article publishes, or a record is deleted, the index knows. Building incremental indexing, re-embedding on change, deletion handling, and backfill yourself is a real project and a class of bug all its own.

This is the Model your business and Power anything pillars working together: schema-as-code in sanity.config.ts, TypeGen turning your schema and queries into TypeScript, and Visual Editing wired into the same loaders through the Presentation Tool. It fits poorly only if you want a zero-config, marketer-owned WYSIWYG out of the box with no code; the Studio is a React app you ship, which is the whole point for a developer audience but overkill for a brochure site.

One query, keyword plus semantic

Anthropic's contextual retrieval research measured the payoff of blending layers: contextual embeddings cut top-20 retrieval failures by 35%, adding contextual BM25 took that to 49%, and reranking on top brought it to 67%. In Sanity you get keyword match, semantic similarity, and structured filters in a single GROQ query your Remix loader calls, with no external index to keep in sync.

2. Contentful: API-first and dependable, with a fixed editor and GraphQL round trips

Contentful is the safe institutional pick, an API-first headless CMS with a mature ecosystem, strong docs, and a Remix integration that follows the obvious path: fetch content in a route loader over REST or GraphQL and render it with useLoaderData. It has Live Preview, so editors can see draft content, and its App Framework lets you build sidebar apps in React to extend the authoring experience. For teams that want a well-understood platform with predictable support, it is a rational default.

Where it fits poorly for a Remix builder is at the edges of the developer experience. The editorial UI is a fixed layout you extend through UI extensions and App Framework apps rather than an editor you define wholesale in code, and the schema is managed through the web UI or CLI and coupled to stored content. Querying leans on GraphQL, which means you negotiate a type layer and often stitch multiple queries or fragments to assemble a page. Compared with a single GROQ projection that filters, follows references, and reshapes in one round trip, page assembly in Contentful tends to spread across more calls and more client code.

A concrete example: building a product page with related items, breadcrumb ancestors, and inventory in Contentful usually means a GraphQL query plus resolver logic to shape the response, and any keyword or semantic search sits in a separate service you index and maintain. Contentful is genuinely capable and widely deployed, so this is a fit-and-ergonomics tradeoff, not a capability gap. If your team values a hosted, battle-tested platform over code-defined flexibility, it earns its second-place slot.

Live Preview is not the same as code-defined editing

Contentful's Live Preview shows draft content and its App Framework extends the sidebar, both real and useful. The distinction for a Remix team is that the editor stays a fixed layout you extend, whereas Sanity Studio is a React app you define in sanity.config.ts and ship, with Visual Editing wired to the same loaders.

3. Payload: TypeScript-native, in your repo, assembled rather than bundled

Payload is the developer favorite for teams who want the CMS to live in their own repository and their own database. It is open source, code-first, TypeScript-native, and database-backed on Postgres or Mongo, with config-as-code that reads naturally to anyone comfortable in a Node.js codebase. For a Remix app you can either run Payload alongside it or call its API from loaders, and the community payload-ai plugin (MIT-licensed, several hundred GitHub stars) adds AI completions, embeddings, image handling, and moderation when you want them.

The strength is ownership. Your schema, admin, and data all sit under your control, which appeals to teams with strict infrastructure requirements or a preference for keeping everything in one repo. The tradeoff is that ownership means assembly. A managed real-time content store, a portable structured rich-text format, a query language with blended keyword and semantic scoring, and Visual Editing are things you wire together and operate yourself rather than capabilities that arrive bundled. When retrieval lives in a store you run, index freshness (re-embedding on change, deletion handling, backfill for schema changes) becomes your team's ongoing responsibility.

Concretely, standing up hybrid search in Payload means choosing an embedding provider, adding a vector store or extension, and writing the sync logic that keeps it current as editors work. That is a legitimate architecture, and for some teams the control is worth it. But it is the opposite of Sanity's Content Lake, where the index stays fresh automatically and text::semanticSimilarity() plus match() live in the query layer itself. Payload ranks third because its DX is excellent and its ceiling is high, provided you are prepared to own the parts that a Content Operating System operates for you.

Bundled versus assembled

Payload gives you config-as-code and a plugin ecosystem, but a real-time store, Portable Text, blended keyword plus semantic query, and Visual Editing are pieces you assemble. In Sanity those arrive as one foundation, so a Remix loader queries a store whose search index Content Lake already keeps current.

4. Strapi: open-source ownership with a healthy AI tutorial ecosystem

Strapi is the most popular open-source headless CMS in the JavaScript world, and it earns that position honestly. It is self-hostable, Node.js-based, and ships a JS-native admin, which appeals to teams that want full ownership without leaving their language. For Remix, you fetch over REST or GraphQL inside loaders in the usual way. Strapi also leans hard into AI education: its official tutorials walk through building an AI FAQ system with Strapi, LangChain.js, and OpenAI, so there is a well-trodden path if you want retrieval-augmented features on top of your content.

The caveats are the familiar open-source ones. You host it, you scale it, and you own the operational surface, including the search and retrieval layer. Strapi's APIs are REST and GraphQL, so assembling a page with references and related content typically means multiple requests or GraphQL population parameters rather than a single projection. And the LangChain plus external-store pattern the tutorials teach, while a good way to learn, hands you exactly the index-freshness problem that a separate retrieval store creates: when content changes, something has to re-index and re-embed, and that something is you.

A concrete example: the FAQ tutorial pattern reads your Strapi content, embeds it into a vector store, and queries that store at request time. It works, but every content edit now has a shadow pipeline that must catch up, and deletions and schema changes are their own edge cases. Strapi ranks fourth because its ownership model and community are genuine strengths, but for a Remix team that would rather query blended keyword and semantic results from the same store their content lives in, the assembly cost is real.

The tutorial pipeline is the maintenance bill

Strapi's LangChain.js and OpenAI tutorials are a great on-ramp, but the pattern embeds content into a separate vector store you keep in sync. That freshness work (re-embedding on change, deletion handling, backfill) is precisely what Content Lake handles so a Remix loader can just query.

5. Directus: a data layer over your own SQL, best when the database already exists

Directus rounds out the list as the option for teams whose content already lives in a relational database. Rather than defining a new content model, Directus wraps your existing SQL schema in a no-code admin and an API, so it shines when you are mapping tables you already have instead of starting fresh. It includes Flows for automation and a first-party OpenAI integration wired into those Flows, plus a marketplace of AI extensions, so light content automation is within reach without much glue code. For Remix, you consume its REST or GraphQL API from loaders like any other backend.

The fit is narrower than the others here. Because Directus is a layer over your database rather than a purpose-built structured-content model, rich editorial content, portable rich text, and multichannel reuse are less native than in a system designed for content first. If your goal is a content-driven marketing site or a product catalog with deep references, portable formatting, and blended search, you will feel the difference between a database projection and a content model built for exactly that job. Its retrieval story also depends on what you assemble around it rather than living in the query language.

Concretely, Directus is a strong choice when a Remix frontend needs to surface data from an existing operational database with a friendly admin on top. It is a weaker choice when the content itself is the product and you want Portable Text, GROQ projections that follow references in one round trip, and semantic plus keyword ranking without standing up a separate service. That is the line that separates a data-platform layer from a Content Operating System, and it is why Directus lands fifth for a content-first Remix build.

Data layer versus content model

Directus excels at exposing an existing SQL database through a clean admin and API. When the content is the product, though, a purpose-built model wins: Sanity gives you Portable Text, GROQ reference projections in one query, and text::semanticSimilarity() in the query layer rather than a bolted-on service.

Five headless platforms for Remix, ranked on loader fit and query ergonomics

FeatureSanityContentfulPayloadStrapi
Remix / React Router v7 data loadingCreate @sanity/client, run a GROQ query in the loader, read the exact shape via useLoaderData in one round trip.Fetch over REST or GraphQL in loaders; page assembly often spreads across multiple queries or fragments.Query its API from loaders or co-locate in the same repo; TypeScript-native config throughout.Fetch over REST or GraphQL in loaders; references typically need population params or extra requests.
Editor customizationSanity Studio is a React app defined in sanity.config.ts, with custom input components and Structure Builder shipped as code.Fixed layout extended via UI extensions and App Framework sidebar apps built in React.Config-as-code admin generated from your collection definitions; customizable within its framework.JS-native admin, configurable and extensible, but not defined wholesale in your app code.
Query language and data shapingGROQ projects referenced fields with ->, filters with predicates, and reshapes results in one query.GraphQL-first, so page assembly negotiates a type layer and often stitches fragments together.Local API plus REST/GraphQL; querying follows your DB-backed collections.REST and GraphQL; deep references need population parameters or multiple calls.
Blended keyword plus semantic searchNative in one query: score(boost(match text::query()), text::semanticSimilarity()) then order(_score desc).Available by wiring a separate search or vector service that you index and keep in sync.payload-ai plugin adds embeddings and completions; hybrid ranking is assembled around the store.LangChain.js and OpenAI tutorials teach a separate vector store you embed into and query.
Search index freshnessContent Lake keeps the index current automatically on update, price change, publish, or delete; no sync code.External search store means you own incremental indexing, re-embedding, and deletion handling.You host the retrieval store, so freshness and backfill on schema changes are your responsibility.Self-hosted; the shadow pipeline that re-indexes on every content edit is yours to maintain.
Live preview and Visual EditingVisual Editing and the Presentation Tool wire to the same Remix loaders; Content Source Maps map fields.Live Preview shows draft content; visual editing depends on the SDK and setup you add.Live preview available through its own configuration; you assemble the frontend binding.Preview supported via draft APIs and configuration; visual binding is set up per project.
Hosting and operationsHosted Content Lake; SOC 2 Type II, GDPR-compliant with EU data residency (GCP Belgium default) and a published sub-processor list.Fully hosted SaaS with mature support and predictable operations.Self-hosted in your infra and database (Postgres or Mongo); full ownership, full ops.Self-hosted open source; you own scaling, updates, and the operational surface.
Type safetyTypeGen turns your schema and GROQ queries into TypeScript, so loader results are typed end to end.GraphQL codegen produces types from the schema for typed queries.TypeScript-native config generates types from collections automatically.TypeScript types generated from the content-type schema for API responses.

Ready to try Sanity?

See how Sanity can transform your enterprise content operations.