Headless WooCommerce: when it's worth it and when it's a trap

Headless WooCommerce promises a faster, more flexible storefront, then quietly turns one website into two systems. Here is how I decide when the split pays for itself and when a well-built classic store wins.

In short

  • The problem: agencies sell headless WooCommerce as a speed and flexibility upgrade, and store owners end up paying for two systems, a broken plugin ecosystem, and a checkout that has to be rebuilt by hand.
  • What I do about it: treat headless as a cost you take on for a specific reason (a content-heavy front end, several storefronts, an app) and keep checkout and account pages on WooCommerce unless there is a strong case to move them.
  • Who this is for: agencies scoping a WooCommerce rebuild, and store owners who have been pitched "go headless" and want to know what they are actually buying.

The pitch usually sounds like this: the current store is slow, the theme is hard to change, so rebuild the front end in React or Next.js and keep WooCommerce "just for the back end". The demo is fast. The product pages look great. Everyone signs off.

Then the real store arrives. The product add-ons plugin renders nothing, because it was written to output fields into a PHP template that no longer exists. The payment gateway's card form was a script loaded on the WooCommerce checkout page, which nobody visits anymore. The SEO plugin's meta tags, the reviews widget, the "frequently bought together" block: each one is now a ticket to reimplement in the new front end.

None of that is a bug. It is what "headless" means. You have removed the layer most WooCommerce plugins were written for, and you now own everything that layer used to do.

Headless means you own two systems, not one faster one

A classic WooCommerce store is one application. PHP renders the page, plugins hook into that render, and the cart, checkout, and account pages all live in the same place.

A headless store splits that in two. WordPress and WooCommerce become an API: products, cart, and orders served as JSON. A separate front end, usually React with Next.js, fetches that data and renders the store. "Headless" just means the back end no longer draws the pages.

That split has real consequences:

  • Two deployments, two hosting bills, two sets of things that can be down. A store that used to be "the website" is now a front end, an API, and the network between them.
  • Two skill sets. Someone has to be good at WooCommerce internals, and someone has to be good at a modern JavaScript framework. On a small team, that is often the same overworked person.
  • A contract between them. Every field the front end shows has to come through an API. When a plugin adds a new product option, it is invisible until someone wires it through.

Headless does not make the back end faster. If your product queries are slow, the API serving them is just as slow. If the real problem is a bloated database or work running inside the checkout request, those causes survive the rebuild untouched.

The plugin ecosystem is the asset you give up

Most of WooCommerce's value is its ecosystem: thousands of extensions for shipping rules, subscriptions, bundles, add-ons, B2B pricing, reviews, and marketing. Most of them assume they can print HTML into WooCommerce's templates or enqueue scripts on its pages.

On a headless front end, a plugin falls into one of three buckets:

  1. Pure back-end logic (tax rules, stock sync, order exports, ERP integrations). These usually keep working, because they act on orders, not pages.
  2. Logic plus a UI (product add-ons, bundles, gift cards, subscription options). The logic may still run, but you rebuild the UI yourself, and you need the plugin to expose its data through an API.
  3. Pure front-end features (sliders, popups, page-builder widgets). These are simply gone, and you rebuild or replace them.

The failure I see most often is an estimate written as if every plugin is in bucket one. Audit the active plugin list before you scope anything. Every plugin in bucket two is real front-end work, and some of them have no API at all.

The Store API makes headless carts possible, not free

WooCommerce ships the Store API, the same API its block-based Cart and Checkout use. It lives under /wp-json/wc/store/v1/ and covers products, the cart, and checkout for anonymous shoppers. That is the piece that makes a headless cart realistic without writing your own endpoints.

For a front end on a different domain, the important detail is the Cart-Token header. A request to /wp-json/wc/store/v1/cart returns a Cart-Token in the response headers. The front end stores it and sends it back on every cart and checkout request, and WooCommerce documents that a nonce is not needed when a cart token is sent:

// Minimal cart client: keep the token, send it back on every call.
const STORE = 'https://shop.example.com/wp-json/wc/store/v1';

export async function storeFetch(path: string, init: RequestInit = {}) {
  const token = sessionStorage.getItem('cartToken');
  const res = await fetch(`${STORE}${path}`, {
    ...init,
    headers: {
      'Content-Type': 'application/json',
      ...(token ? { 'Cart-Token': token } : {}),
      ...init.headers,
    },
  });
  const next = res.headers.get('Cart-Token');
  if (next) sessionStorage.setItem('cartToken', next);
  if (!res.ok) throw new Error(`Store API ${res.status}`);
  return res.json();
}

That is the easy part. The harder parts are what the snippet hides: CORS configured so the browser can read that header, a cart that survives the shopper switching tabs or devices, and every plugin that changes cart totals doing it in a way the Store API sees. I wrote about that last one in extending the Store API without breaking the cart. The short version: code that only hooks the classic shortcode checkout will not change what the Store API returns.

If the team prefers GraphQL, WPGraphQL for WooCommerce (WooGraphQL) is the community option. It is a separate open-source project, not maintained by WooCommerce, and it needs WPGraphQL installed alongside it. Fine for many stores, but it is another dependency whose release schedule you do not control.

Checkout is where headless projects go over budget

Rendering product pages from an API is a solved problem. Checkout is not, because checkout is where the store's most fragile integrations live: payment gateways, fraud checks, address validation, shipping rates, coupons, and tax.

Payment gateways are the hardest piece. Many WooCommerce gateway plugins render their card fields with scripts on the WooCommerce checkout page, and some redirect to the provider and back. A headless checkout has to reproduce that flow: load the provider's own SDK in your front end, tokenize the card there, and pass the result to WooCommerce in a shape the gateway plugin accepts. Strong customer authentication steps, such as 3-D Secure challenges, have to work inside your UI too. Having built payment integrations for WooCommerce, Shopify, and Magento at Paysera, I treat every gateway in a headless scope as its own line item, not a checkbox.

That is why my default for most headless WooCommerce builds is a hybrid: product, category, and content pages are headless, and the cart hands off to WooCommerce's own checkout on a subdomain or path, styled to match. You keep every gateway, every checkout extension, and every fix WooCommerce ships, and the fast, custom experience covers the pages where shoppers spend most of their time. WooGraphQL's own docs recommend handing the session back to WordPress for checkout, which tells you how common this pattern is.

Headless pays off for content-led brands, multiple storefronts, and apps

There are good reasons to go headless. They are specific:

  • The store is mostly content. A brand where editorial pages, lookbooks, and campaigns drive sales, and the design team needs freedom the theme cannot give. The catalog is modest and the checkout is standard.
  • One catalog feeds several front ends. A web store, a mobile app, an in-store kiosk, or a second brand site all selling from the same WooCommerce inventory. Here the API is the product, and you would build it anyway.
  • The front end is already a JavaScript application. A SaaS or community platform that adds a shop. Rendering the shop inside the existing app is often less work than bolting a WordPress theme onto it.
  • There is a front-end team to own it. Not a contractor who leaves after launch. Headless without a long-term front-end owner turns into a site nobody can change.

When I scope one of these, the reason goes in the first line of the proposal. If nobody can write it in one sentence, the project is probably headless for the sake of being headless.

When a well-built classic store is the better call

I steer away from headless when:

  • The real complaint is speed. Classic WooCommerce with a lean block theme, a page cache, an object cache, and an audited plugin list is fast enough for most stores. Fix the slow thing directly before you add a second system.
  • The store depends on many UI-heavy plugins. Bookings, complex product configurators, memberships, and subscriptions with custom options all multiply front-end work.
  • The budget covers the build but not the years after. Every WooCommerce and plugin update now has to be checked against two systems. If maintenance is not funded, the front end drifts from the back end within a year.
  • The team is one person. A single engineer can own a classic store. Owning a Next.js front end, its hosting, an API layer, and WooCommerce is a lot for one person to keep healthy.
  • SEO is the main channel and nobody owns rendering. A headless front end can rank very well, but only if pages are server-rendered or statically generated, with meta tags, structured data, and redirects that the SEO plugin used to handle. That is now your code.

If the platform itself is the doubt, compare options before choosing an architecture. My notes on WooCommerce vs Shopify for custom builds cover that decision.

Trade-offs I put in writing before anyone signs off

Every headless proposal I would stand behind lists these explicitly, so the client is choosing them, not discovering them:

  • Build cost goes up, often a lot. You are building a front end and keeping a back end, and every plugin with a UI becomes custom work.
  • Running cost goes up. Two hosts, two deploy pipelines, two sets of monitoring.
  • Plugin choices narrow. "Can it be used headless?" becomes a filter on every future extension.
  • Preview gets harder. Editors expect to see a draft before publishing. In a headless setup someone has to build that preview.
  • What you gain: design freedom, a fast and app-like browsing experience, a catalog API you can reuse elsewhere, and a front-end team that does not need to know PHP.

If the gains do not clearly outweigh that list for this business, the honest recommendation is a classic store built well.

What I check before recommending headless WooCommerce

  1. Can the reason be written in one sentence? Content freedom, several storefronts, or an existing app. "It's faster" alone is not a reason.
  2. Which active plugins have a front-end UI, and which expose an API? Each one without an API is a rebuild or a replacement.
  3. Which payment gateways are needed, and do their providers offer a front-end SDK? If not, plan a hybrid checkout.
  4. Will checkout stay on WooCommerce? My default answer is yes, unless there is a funded reason to move it.
  5. Who owns the front end after launch? A named person or team, with time budgeted every month.
  6. How will editors preview content? If nobody has an answer, it will be the first complaint after launch.
  7. Is the back end healthy? Slow queries, bloated tables, and heavy checkout hooks need fixing first, because headless does not hide them.
  8. What does year two cost? Updates, two hosting bills, and keeping two systems in sync.

My verdict: headless WooCommerce is worth it when the front end has a job a theme genuinely cannot do (content-led design, several storefronts, or a shop inside an existing app) and there is a team to own it for years. For most stores that just want to be faster and look better, a lean classic build wins on cost, plugins, and risk. When headless is the right call, go headless where shoppers browse and leave checkout to WooCommerce until you have a strong reason to rebuild it.