What Headless Commerce Actually Means — and What AI Crawlers Can’t Read
- Headless commerce means the storefront your customers see is a separate application from the commerce engine that holds products, carts, and orders. The two talk over an API instead of running as one codebase.
- Headless is not one decision, it is two. Decoupling the front end is the architecture decision. Choosing where the HTML gets built — on the server or in the browser — is the rendering decision, and that second one is the one with a search consequence.
- AI answer engines do not run JavaScript. Vercel and MERJ measured 569 million GPTBot requests and 370 million Claude requests and found none of the major AI crawlers execute it. A storefront that assembles its product text in the browser is blank to them, even though Google reads it fine.
- Two things are not yours to choose. On Shopify the checkout stays Shopify-hosted — the Storefront API hands you a
checkoutUrland you redirect. On WooCommerce the Store API is unauthenticated and session-scoped, so anything needing real customer data needs a second authenticated service you build and secure. - Decide from requirements, not revenue: a second front end you must ship, a design the theme layer genuinely cannot express, or a measured server-render ceiling. No requirement on that list, no headless.
Headless commerce is usually sold as an architecture decision and argued about as a performance decision. It is neither, on its own. Decoupling the storefront from the commerce engine is one choice; deciding where the HTML is assembled is a second, independent choice that most explainers fold into the first. Getting them confused used to cost nothing, because Google renders JavaScript and has for years. It costs something now: the crawlers behind AI answer engines do not render JavaScript, so a storefront that builds its product copy in the browser is invisible to them while ranking normally in Google. This post separates the two decisions, states what each platform will and will not let you control, and gives you a one-command check for what a non-rendering crawler actually receives from your store.
Contents
- What headless commerce actually means
- Headless and client-side rendering are two different decisions
- Why AI crawlers cannot read a client-rendered storefront
- Google renders JavaScript — which is why this went unnoticed
- How to check what a crawler actually receives
- On Shopify, you do not rebuild the checkout
- On WooCommerce, the Store API is the entire contract
- What headless does not solve
- Which architecture fits which requirement
- The pre-decision checklist
What headless commerce actually means
Headless commerce means the presentation layer is a separate deployable application from the commerce engine, and the two communicate over an API. The engine keeps the product catalogue, pricing, cart state, inventory, and orders. The storefront keeps templates, routing, and interaction. In a conventional WooCommerce or Shopify store those responsibilities live in one system: a theme renders pages inside the same process that owns the cart.
The word “head” refers to the presentation layer. Removing it leaves an engine that answers API calls and renders nothing, which is why the same back end can serve a website, a native app, an in-store kiosk, and a partner integration without three copies of the catalogue.
What headless does not mean is a change of commerce engine. Products, tax rules, discounts, fulfilment state, and order history stay exactly where they were. You are moving the rendering layer, not the business logic — which is the reason so many headless projects deliver a new storefront and an unchanged set of back-office problems.
Headless and client-side rendering are two different decisions
Decoupling the front end does not dictate where HTML is built. Those are separate choices, and conflating them is the single most common error in headless planning. A decoupled storefront can render on the server and ship complete HTML; a conventional themed store can hollow itself out with client-side widgets and ship almost nothing.
The architecture decision is whether the storefront is a separate application talking to a commerce API. The rendering decision is whether the HTML for a product page is assembled on a server before the response is sent, or assembled in the visitor’s browser after JavaScript loads and calls the API itself.
Frameworks used for headless storefronts support both modes, and the default is not always the safe one. Server-side rendering and static generation both put product text in the initial HTML response. Client-side rendering puts an empty shell in the response and fills it in afterwards. Every consumer that does not run JavaScript — and there are more of them than there were two years ago — sees only the shell.
The diagram below shows the same headless back end under both rendering modes, and what each one puts in the first response.
Both paths are headless. Only one of them is legible to a client that does not execute scripts.
Why AI crawlers cannot read a client-rendered storefront
AI answer engines fetch your HTML and parse it. They do not run your JavaScript. If the product name, price, and description are injected into the page after load, the crawler stores an empty container and your product is absent from the model’s view of the web.
According to Vercel and MERJ’s crawler analysis published on 17 December 2024, none of the major AI crawlers render JavaScript, across OpenAI, Anthropic, Meta, ByteDance and Perplexity products. The same analysis, drawn from 569 million GPTBot requests and 370 million Claude requests, found that these crawlers do fetch script files — GPTBot in 11.50% of requests, Claude’s crawler in 23.84% — without executing any of them. Fetching is not running: the file is downloaded and discarded.
An independent set of live tests published in August 2025 reached the same result from the other direction, prompting the assistants directly with URLs from a client-rendered site. ChatGPT reported that it could not read the page because it relied on JavaScript-based rendering, and Claude reported that it could not retrieve any text from the page.
Two exceptions are worth knowing. Google’s Gemini rides on Googlebot’s infrastructure and renders fully, and Applebot uses a browser-based crawler that also renders. Everything else in that list does not. This is why a headless store can hold its Google rankings and still never appear in an assistant’s answer — the two systems are not looking at the same page.
Treat this behaviour as current rather than permanent. Crawlers change, and no vendor is obliged to announce it. The section after next gives you a check you can run against your own URLs in under a minute, which beats trusting any article about it, including this one.
Google renders JavaScript — which is why this went unnoticed
Google has rendered JavaScript for years, which is precisely why client-side rendering became normal in commerce front ends without anyone treating it as a risk. Teams shipped single-page storefronts, watched rankings hold, and concluded that rendering strategy was a performance question rather than a visibility question.
That conclusion was correct for the surface it was tested against. It does not transfer. Google’s renderer is an expensive piece of infrastructure that AI crawlers have not replicated, so the assumption “it works for Googlebot, it works everywhere” quietly stopped being true while the evidence for it — stable organic rankings — kept looking reassuring.
The practical consequence is that your existing analytics will not warn you. Organic sessions stay flat. Rankings stay put. The traffic you lose is traffic that never had a chance to exist: a buyer asking an assistant which supplier stocks a part, receiving three competitors, and never seeing a link to you. There is no line in a report for an answer you were left out of, which is what makes this failure mode expensive and slow to notice. The same asymmetry drives the wider shift covered in the guide on what agentic commerce actually ships today versus what is only announced.
How to check what a crawler actually receives
Request your own page without a browser and look for your product text in the raw response. That is the entire test, and it needs no tooling beyond curl and a terminal.
# Fetch a product page exactly as a non-rendering crawler would
curl -sL "https://example.com/products/cold-brew-concentrate" -o /tmp/page.html
# Does the initial HTML contain the product name?
grep -c "Cold Brew Concentrate" /tmp/page.html
# Does it contain the price and the description copy?
grep -c "24.00" /tmp/page.html
grep -oE "Slow-steeped[^<]{0,60}" /tmp/page.html
A count of zero means the text is not in the response. A count of one or more means it is present before any script runs, which is what you want. Run the same three commands against a category page, the homepage, and one page whose content loads inside a tab or accordion — those are the usual places where server rendering is complete and a widget still is not.
Two refinements make the result trustworthy. Compare the byte size of the curl response against what the browser’s network panel reports for the document request; a large gap between them is the signature of a shell page. And check the pages that matter commercially rather than the ones that are easy to test — a server-rendered homepage in front of client-rendered product detail pages is a common and costly combination.
If the check fails, the fix is a rendering-mode change in the front-end framework, not a rebuild. Switching a route from client rendering to server rendering or static generation is usually a configuration and data-fetching change confined to that route.
On Shopify, you do not rebuild the checkout
A headless Shopify storefront does not include a custom checkout. You build catalogue, cart, and account surfaces against the Storefront API, then hand the buyer back to Shopify to pay. The Cart object exposes a checkoutUrl field, documented as “the URL of the checkout for the cart”, and Shopify’s own guidance is to query it when the buyer is ready and redirect: the response is a URL that sends customers through Shopify’s web checkout.
This matters for planning because the checkout is where most of the perceived upside of a custom storefront lives. The common expectation going in is a bespoke, single-page, brand-controlled purchase flow. What the platform supports is a bespoke path up to the cart and then a redirect. Shopify’s own framework for headless storefronts, Hydrogen, is described as a batteries-included framework with prebuilt components, and its hosting layer, Oxygen, as a global edge platform — neither changes the checkout ownership.
Read this as a constraint that removes work rather than one that blocks it. Payment handling, PCI scope, fraud tooling, and wallet support stay on the platform’s side of the line, which is a meaningful reduction in what you build and certify. It simply needs to be known before a design is signed off, not discovered during it. The broader direction of the platform is covered in the analysis of how Shopify’s back-office expansion changes the integration picture.
On WooCommerce, the Store API is the entire contract
WooCommerce’s headless surface is the Store API, and its defining property is that it is unauthenticated. WooCommerce documents it as public REST endpoints for building customer-facing cart, checkout, and product functionality, built specifically to enable non-authenticated client-side functionality such as a custom block or a headless WooCommerce store. It is at version v1.
Unauthenticated is the load-bearing word. The Store API is scoped to the current session: it will not look up other customers or their orders by ID, and it will not write store data such as settings. Write operations are protected by a nonce token rather than a credential. Anything requiring real customer identity — order history across sessions, saved addresses, subscription management, B2B account pricing — falls outside it.
The consequence is architectural. A headless WooCommerce storefront that needs authenticated customer features needs a second service holding credentials and calling the authenticated WooCommerce REST API server-side, which you build, host, secure, and rate-limit yourself. That service is where headless WooCommerce budgets tend to be spent, and it is absent from most feature comparisons. Where the Store API is and is not worth it in practice is worked through in the deep dive on headless WooCommerce and the Store API.
Note the asymmetry against Shopify. WooCommerce will let you own the checkout through the Store API’s checkout endpoints; Shopify will not. That is the reverse of what most platform comparisons imply, and it is the single largest scope difference between the two headless paths.
What headless does not solve
Headless changes where pages are rendered. It does not change what the data says, how orders reach the back office, or why customers abandon carts.
It does not fix conversion. Cart abandonment is driven by shipping cost, delivery certainty, payment methods, and trust signals, all of which survive a front-end rewrite untouched. On Shopify the checkout is not even yours to change.
It does not fix integration. Inventory, pricing, and order data still have to move between the store and whatever system owns them, on the same schedule and with the same failure modes. The decision between event-driven and scheduled movement is unaffected by the storefront, as set out in the framework for choosing between webhooks and polling for inventory sync. If catalogue data is wrong in the engine, headless renders it wrong faster.
It does not fix content operations. Marketing teams that could edit a page in the theme editor will file tickets against a front-end repository instead, and content velocity usually falls in the first two quarters after launch.
It does not automatically fix performance either. Serving pre-built HTML from a CDN is fast, but a conventional store with full-page caching in front of it is also serving pre-built HTML from a cache — the claim that a themed store re-renders every page on every request is only true when caching has been misconfigured. Measure the current server-render ceiling before treating performance as the justification. Where build-versus-configure trade-offs are priced properly is covered in the breakdown of how per-step billing changes the no-code versus custom-code maths.
Which architecture fits which requirement
Requirements decide this, not revenue. The table maps the three requirements that genuinely justify a decoupled storefront against the two that do not, and states what each implies for rendering.
| Requirement | Headless justified? | Rendering mode required |
|---|---|---|
| A second front end — native app, kiosk, or partner surface — reusing one catalogue and cart | Yes. This is the strongest case and the hardest to retrofit later. | Server rendering on the web surface; the app surface is unaffected |
| A storefront design the theme layer genuinely cannot express, verified by a failed attempt | Yes, once “cannot” has been tested rather than assumed | Server rendering or static generation, per route |
| A measured server-render ceiling that caching and query work have not moved | Yes, after the measurement — not before it | Static generation for catalogue, server rendering for cart |
| Storefront speed, with caching unexamined | No. Fix the cache and the queries first; the ceiling is usually not where it is assumed to be | Not applicable |
| Search visibility or SEO | No. Google already renders JavaScript, and AI crawlers do not — headless changes neither, rendering mode changes both | Not applicable |
Verdict: adopt headless when a second front end exists or a design requirement has survived a real attempt in the theme layer. Choose server rendering or static generation in every case. If no row above describes your situation, the honest answer is that the current architecture is not the constraint.
The pre-decision checklist
Work down this list before committing to a decoupled storefront. Each item is a check with an answer, not a discussion point.
- Name the second front end that will consume the same commerce API, and the quarter it ships. If there is no second front end, remove multi-channel from the justification.
- Attempt the blocking design requirement in the current theme layer and record where it fails. An untested “the theme cannot do this” is not a requirement.
- Measure current server response time at peak with full-page caching correctly configured, and record the number that headless is expected to beat.
- Run the curl check above against a product page, a category page, and the homepage of any candidate reference build, and record whether product text appears without JavaScript.
- Confirm the rendering mode for every route in the proposed front end. Any route left on client rendering is a route AI crawlers cannot read.
- List the authenticated customer features in scope — order history, saved addresses, account pricing — and identify which service will hold credentials, since the WooCommerce Store API will not.
- On Shopify, confirm with stakeholders in writing that the checkout will remain Shopify-hosted and reached by redirect.
- Identify who edits storefront copy after launch and through which workflow. If the answer is a pull request, budget for the drop in content velocity.
- Price the ongoing cost of two deployment targets — front end and back end — including who is on call for each.
- Re-run the curl check on the live build before launch and again 30 days after, since a framework upgrade can silently change a route’s rendering mode.
If most items resolve cleanly, headless is a reasonable fit and the rendering decisions are already made. If the first three do not resolve, the project is a storefront redesign wearing an architecture label, and it will deliver a new front end on top of the same unsolved problems. Where this sits in the wider integration picture is mapped in the NetSuite and WooCommerce integration guide library, and if the constraint turns out to be the back office rather than the storefront, that is the kind of integration work we take on.
Get the working checklists
The runbooks and decision checklists from these guides, as printable PDFs — free in the SoftXone guide library.
References
- WooCommerce Store APIWooCommerce developer documentation — the unauthenticated Store API, its endpoints, session scope, and stated limits.
- Shopify Storefront API — Cart objectShopify developer documentation — the Cart object and the checkoutUrl field definition.
- Shopify — Manage a cart with the Storefront APIShopify developer documentation — querying checkoutUrl and redirecting the buyer to Shopify’s web checkout.
- Shopify — Headless storefrontsShopify developer documentation — Hydrogen as the headless framework and Oxygen as its edge hosting platform.
- The rise of the AI crawlerVercel and MERJ, 17 December 2024 — crawler measurement across 569 million GPTBot and 370 million Claude requests, including JavaScript execution behaviour.
- AI search and JavaScript renderingG-Squared Interactive, 11 August 2025 — live tests prompting ChatGPT, Claude and Perplexity with URLs from a client-side rendered site.
- Getting started with WooCommerce APIsWooCommerce developer documentation — how the Store API and the authenticated REST API differ in scope.
Frequently asked questions
Does going headless improve my Google rankings?
Not by itself. Google renders JavaScript, so organic visibility is largely unaffected by the decoupling decision in either direction. Where headless builds do gain ground, the gain usually comes from faster page delivery — and a conventional store with full-page caching correctly configured often reaches the same delivery speed without a rewrite. Measure the cached response time first. The visibility difference that does depend on rendering mode shows up in AI answer engines, not in Google.
Can I keep my WooCommerce plugins on a headless storefront?
Partly. Plugins that render front-end output stop applying, because the theme layer they hook into no longer runs. Plugins that operate server-side on orders, tax, inventory, or fulfilment keep working, since the commerce engine is unchanged. Before committing, inventory every plugin you depend on and mark each one front-end or server-side. That inventory is the most common source of unplanned work in a headless migration, because the front-end half has to be rebuilt as application code.
How can I tell whether my current store already has this problem?
Run the curl check in this post against your product pages and look for the product name in the raw HTML. Then read your access logs for the AI crawler user agents — GPTBot, OAI-SearchBot, ClaudeBot and PerplexityBot. If those agents are fetching your pages regularly and the pages are client-rendered, they are collecting empty shells on every visit, and the crawl volume in your logs will look healthy while nothing usable is being stored.
Is static generation safe for a store with frequent price changes?
Static generation serves HTML built ahead of the request, so prices can go stale between builds. Frameworks pair it with a revalidation window or an on-demand rebuild triggered by a webhook from the commerce engine when a product changes. Size the window against how often your prices actually move, not against a default. Cart, checkout, and any account page should stay server-rendered regardless, since their content is per-visitor and cannot be built in advance.
Does headless change my PCI scope?
It depends on which platform path you take. On Shopify the checkout stays hosted by the platform and the buyer is redirected to it, so card data never reaches your front end and scope stays where it was. On WooCommerce the Store API exposes checkout endpoints, so you can own the flow — and owning it can pull your own infrastructure into scope unless the payment gateway’s hosted fields or redirect keep card data off your servers. Settle this before the platform decision, not after it.

Leave a Reply