Starting constraint
The store had grown into a Frankenstein: many plugins, several years of theme overrides, a checkout that worked, and Core Web Vitals that did not. The buyer wanted a headless front but refused to break checkout, refused US-jurisdiction-only hosting, and refused to lock the front-end framework for the next decade.
Three constraints that, taken together, narrowed the architecture quickly.
Architecture decision
WooCommerce stayed the commercial source of truth. The front end moved to Astro on Cloudflare Pages with Workers for edge logic. UCP provided the integration boundary so that the front-end could be re-written later without touching the commercial back-end.
Cloudflare won on EU jurisdiction, on TTFB across European traffic, and on cost predictability. UCP won by being open and reversible, not by being trendy.
Cart and checkout boundary
The cart was a React island inside the Astro shell. The checkout stayed on WooCommerce inside an iframe-free, redirect-based hand-off. That kept payment compliance, tax handling, and stock movements inside WooCommerce, which is where the buyer's accountant wanted them.
Most of the perceived speed gain came from the catalogue side. Static-rendered category and product pages with edge cache, plus a small client-side cart hydration, beat the previous full-PHP-rendered store handily.
Delivery model
Delivery was incremental: catalogue first, search second, cart third, checkout last. Each stage shipped behind a feature flag at the edge. Rollback was a flip, not a deploy.
Editorial and product teams continued working in WordPress admin. Headless did not change their day. That was a deliberate decision.
Outcome bands
Exact numbers are confidential. Publishable: catalogue Core Web Vitals moved into green, TTFB across the European traffic mix dropped meaningfully, and the buyer reduced exposure to a single hosting jurisdiction.
The reusable lesson: headless WooCommerce wins not by replacing WordPress, but by drawing a clean integration boundary so each layer can be improved without touching the others.