You’re not headless. You’re hybrid — and that’s the CMS 12 default.
For CMS 12 / Commerce teams with a React (or similar) storefront who keep hearing “just go headless” or “just move to Graph.” This is Part 1 of Find → Graph: the hybrid storefront.
Optimizely CMS 12 sites that look “headless” in the browser are usually hybrid.
Editors still work in the CMS. Catalog still lives in Commerce. Preview and on-page edit still need a server-rendered page. React (or similar) is a storefront shell, not the system of record.
If you skip that, CMS 13 + Optimizely Graph feels like a frontend rewrite. It isn’t. Graph replaces Search & Navigation (Find) as the query/index layer.
It does not replace:
- Content types and
IContentRepository - Commerce catalog, pricing, and cart
- Edit mode and preview
- Your React / SSR host
Three layers people mix up
| Layer | CMS 12 today | After Graph / CMS 13 |
|---|---|---|
| Authoring | CMS UI, content types | Still CMS |
| Storefront | Razor + React / Content Delivery API | Same hybrid, or more CDA |
| Search and listings | Find (IClient, facets, conventions) |
Optimizely Graph |
Content Delivery API is content over HTTP. Find/Graph is query, facet, rank, and index. Using CDA as your product-listing search is how teams paint themselves into a corner.
A hybrid shape that survives Graph
- CMS/Commerce owns content and catalog.
- A thin .NET host does auth, cart, preview, and first paint (SSR).
- React hydrates listing / PDP / checkout islands.
- Listings talk to a query module (
IProductSearch,IPageSearch) — notIClientin 40 controllers.
That last point is the migration. Find behind a port → Graph is an adapter. Find in every controller → Graph is a rewrite.
public interface IProductSearch
{
Task<ProductSearchResult> SearchAsync(
ProductSearchRequest request,
CancellationToken cancellationToken);
}
// CMS 12: Find adapter implements this.
// CMS 13: Graph adapter implements this.
// Controllers and React never take a dependency on IClient.
Do this before
- Draw the line: CDA vs Find vs
IContentLoader. - Put Find behind interfaces (search, facets, paging).
- Don’t let React own search URLs the server doesn’t know.
- Measure three numbers: time from publish until the listing shows the new item in Find; listing p95; percent of searches with zero hits.
This is Part 1 of Find → Graph: the hybrid storefront. Next: typed Find query builders, facets, and GetContentResultAsync — so a Graph adapter can sit beside them later.
Comments