Headless ecommerce: the decision to make before the architecture
Going headless moves responsibility onto your team. You get control over the customer experience and your release schedule, and in exchange you take on integrations, monitoring and incident handling that a platform vendor used to cover. This guide explains when that exchange makes sense and when it does not.
Technical review: monkydot engineering
1. What headless actually means
In a headless ecommerce setup the customer-facing storefront is separated from the commerce backend. Instead of a platform theme rendering the pages, the storefront calls APIs for the catalogue, prices, cart, customer accounts and orders.
The definition says nothing about quality. A slow storefront that calls ten services is still headless, and so is a frontend so tightly coupled that it breaks whenever the backend is deployed. It is more useful to judge the setup by who owns each part, how independently the parts can be released and how the store behaves when something fails.
| Term | What it commits you to | What it does not guarantee |
|---|---|---|
| Headless | An interface between the frontend and the commerce backend | Modularity, lower cost or independent teams |
| Composable | Capabilities that can be chosen and replaced as separate components | That each component should come from a different vendor |
| MACH | Applying microservices, API-first, cloud-native and headless principles to the architecture | A required product list or a single big-bang replatform |
2. Headless, composable and MACH are separate decisions
The three terms overlap, but each answers a different question. Headless is about the interface between frontend and backend. Composable is about which capabilities sit behind separate boundaries and which vendors supply them. MACH is a wider set of architectural principles. When teams use the words interchangeably, they tend to end up with more services than they need and less clarity about who is responsible for what.
For many stores a sensible first step is one commerce backend and one storefront. Search, content, promotions or checkout can be split out later if there is a concrete reason: a different pace of change, scale, compliance requirements or a separate owning team.
- Go headless when the customer experience needs to change independently of commerce administration.
- Draw composable boundaries around capabilities that have their own owner or their own replacement cycle.
- Use MACH principles as constraints that keep the system portable, interoperable and observable.
- Resist reading the acronym as a target number of services.
3. Check the business case before choosing the stack
Headless justifies its cost when the current platform keeps getting in the way of work that matters. One unusual landing page is not a reason. Look for requirements that come back again and again across markets, channels, pricing, content, checkout or release management.
| Signal | Headless makes more sense when | An integrated platform is enough when |
|---|---|---|
| Experience | Several channels need one commerce core with different customer journeys | A standard theme covers the roadmap |
| Pace of change | Frontend and backend teams need to release independently | One small team looks after the whole store |
| Markets | Markets differ in catalogue, content, tax, payment or fulfilment | Localisation is mostly translation and currency |
| Operations | The company can take on on-call duty, integrations and data quality | The business expects the platform vendor to handle incidents |
| Economics | The cost of blocked growth or platform workarounds is higher than the added running cost | The case rests only on lower licence fees |
4. Draw a reference architecture with named owners
The first diagram should be plain. Put the storefront at the edge, add a backend-for-frontend only where you need orchestration, keep transactional rules in the commerce core and place external systems behind adapters you control. Show data flows and owners rather than vendor logos.
The storefront can cache public product data, but it should never become the authority for price, entitlements, stock reservation or order status. Those decisions belong on the server, as close as possible to the system of record.
- Mark every synchronous dependency on the customer's path.
- Write down the timeout, retry and fallback behaviour for each dependency.
- Give every field one source of truth, rather than assigning whole objects to a system.
- Version your contracts and record which consumers can tolerate which changes.
| Layer | Main responsibility | Should not own |
|---|---|---|
| Storefront | Rendering, interaction, presenting the session | The final price or stock figure |
| BFF / API layer | Aggregation, channel rules, shaping responses | A second copy of the product master |
| Commerce core | Cart, price calculation, order and promotion rules | Editorial content |
| PIM / CMS | Product enrichment and content editing | Payment or order status |
| ERP / OMS | Financial, fulfilment or allocation data, as agreed | Storefront presentation |
| Event / job layer | Reliable propagation and retries | Business rules that nobody owns |
5. Treat SEO as a rendering and URL contract
Google can render JavaScript, but whether your pages get found should not depend on the client-side app booting correctly. Indexable category, product and editorial pages should come back as useful HTML, with real status codes, stable links and consistent canonical tags in the first response.
Pick the rendering method per route. Static generation or cached server rendering suits public catalogue pages. Dynamic server rendering suits pages that vary per request but still need to be indexed. Client-side rendering belongs behind a login or in interactions where indexing does not matter.
- Keep URL mappings and redirects intact during the migration.
- Generate canonicals, hreflang and structured data from managed data sources.
- Return 404 or 410 for missing content instead of an error page with status 200.
- Track field Core Web Vitals by template, market and device.
| Route type | Default rendering | How to check it |
|---|---|---|
| Product / category | Static or cached server rendering | Content and links are present without client JavaScript |
| Editorial | Static rendering | Canonical, metadata and structured data match the page |
| Search results | Server rendering only if you want them indexed | Facet rules stop crawl traps |
| Account / cart | Dynamic or client rendering | Private data is never stored in a public cache |
6. Settle data ownership before writing integration code
Most headless incidents are data-contract problems that show up in the frontend. Product names, whether an item can be sold, price, stock and the delivery promise often come from different systems and update at different times.
Build an ownership matrix at field level. For each critical value, record which system is the authority, how the value is propagated, how fresh it needs to be, what happens when it is unavailable and how differences are reconciled. Keep in mind that a cache is only a copy.
| Data | Usual authority | How the storefront handles it |
|---|---|---|
| Product enrichment | PIM | Cached and searchable; delayed updates are acceptable |
| Editorial content | CMS | Cached; invalidated when published |
| Price | Commerce or pricing service | Show a cached price; recalculate at transaction time |
| Available-to-sell | Inventory / OMS | Show a helpful signal; reserve before confirming |
| Order status | Commerce / OMS, depending on the stage | Read model with timestamps and source |
7. Model checkout as a state machine
It helps to stop thinking of checkout as a sequence of pages. In practice it is a distributed transaction covering price, stock, tax, delivery, payment and order creation. Model the states and transitions explicitly, including retries, expiry and what gets undone when a step fails.
Recalculate the authoritative totals before taking payment. Use idempotency keys for every order and payment change. Store enough context to resume safely after redirects, authentication steps or a slow payment provider.
- Define when stock is checked, reserved, released and deducted.
- Separate payment authorisation from capture where your fulfilment rules require it.
- Make sure a repeated submit, webhook or callback does no harm.
- Show the customer a state they can recover from, so they are not left guessing whether an order exists.
- Give your operations team a trace from cart to payment to order.
8. Keep the security surface small
A separate storefront means more APIs and therefore more authorisation decisions. Authenticate the user, then check that they may perform this action on this specific resource. A valid session on its own does not mean a customer may read a given order, address or price list.
Keep card data out of your own systems wherever the payment design allows. Use hosted or tokenised payment components from the provider, keep secrets on the server, verify webhook signatures and give each service only the access it needs.
- Test object-level and function-level authorisation on every private endpoint.
- Rate-limit login, cart, promotion code and account recovery, which are the usual abuse paths.
- Keep administrative APIs off the storefront proxy.
- Classify personal data and define how long it is kept and how it is deleted.
- Threat-model third-party scripts, since they run inside the payment journey.
9. Deliver in vertical slices
A programme that starts with the platform can spend months building services without ever proving that a customer can buy something. A better approach is to deliver one thin slice end to end: catalogue, price, cart, checkout, order and the back-office steps that follow. It surfaces gaps in ownership and integration early, while rolling back is still cheap.
- Roll out progressively by traffic share or by market.
- Fix the URL and order contracts before working on visual polish.
- Reconcile old and new systems throughout the migration window.
- Where possible, make rollback possible without a full redeploy.
| Phase | Scope | Done when |
|---|---|---|
| Discover | Journeys, systems, ownership, TCO baseline | A signed decision record and a source-of-truth map exist |
| Prove | One representative vertical slice | It works against real systems, survives failure tests and the operations team can run it |
| Migrate | Templates, markets or customer groups in controlled waves | Parity checks pass and rollback has been tested |
| Optimise | Performance, conversion and running cost | The backlog is driven by measured constraints |
10. Monitor the customer journey as a whole
Servers being up does not mean the shop is working. A storefront can return 200 while prices are stale, stock cannot be reserved or payment callbacks are stuck in a queue. Monitor business transitions and data freshness alongside latency and error rates.
Every alert needs an owner, a description of what it means for customers and an agreed response. Dashboards without runbooks rarely shorten an incident.
- Pass request and correlation IDs through the storefront, commerce backend and integrations.
- Measure checkout transitions, payment outcomes, order creation and sync delay.
- Alert on queue age, dead letters, stale catalogue data and reconciliation differences.
- Define how search, recommendations, reviews and content behave when they are degraded.
- Rehearse restores, provider outages and rollbacks before peak season.
11. Model TCO as the cost of everything you will own
Comparing licence fees does not give you a TCO. Include the build, migration, cloud, vendors, monitoring, security, QA, content tools, support, upgrades and the internal time needed to coordinate all of it.
Model at least three years and include the cost of leaving. Headless may reduce what the platform's limitations cost you while increasing what you spend on engineering. The decision holds up only if the net result fits the operating plan.
| Cost area | Questions to put a price on |
|---|---|
| Build and migration | Data, URLs, integrations, parity, parallel running and rollback |
| Running | Cloud, SaaS, support, on-call, incident response and data operations |
| Change | New features, regression testing, API and dependency upgrades |
| Risk | Peak capacity, vendor failure, compliance work and reliance on key people |
| Exit | Data export, contract termination, replacing components and retraining |
12. Choose a partner on evidence of how they operate
A good partner will question whether you need headless at all, map who owns which system and explain how the store behaves when a dependency fails. A polished component demo tells you very little about any of that.
- Ask for an architecture decision record rather than a generic proposal.
- Review sample runbooks, test plans and data contracts.
- Meet the people who will actually deliver the project and handle incidents.
- Link acceptance to working customer journeys and operational evidence.
| Question | Good answer | Warning sign |
|---|---|---|
| When should we not use headless? | They name thresholds for team size, economics and requirements | Headless is presented as the natural upgrade for everyone |
| Who looks after production? | A clear model for support, SLOs, escalation and handover | Operations is only discussed after launch |
| How do you protect checkout? | State handling, idempotency, reconciliation and failure tests | Only happy-path UI tests |
| How would we leave? | Data, code, infrastructure and documentation can be moved | Critical logic stays in proprietary tooling |
13. Final decision checklist
A cleaner target diagram is not a reason to approve the programme. Approve it when the organisation is able to live with the consequences.
- The business capabilities that are blocked today are specific and keep coming back.
- Headless, composable and MACH are treated as separate decisions.
- Every critical field and order state has a single authority.
- Rendering, URLs, metadata and migration redirects have acceptance tests.
- Checkout has explicit states, idempotency and reconciliation.
- Security covers authorisation at resource level and the scope of payment data.
- The first release is a vertical slice that can be rolled back.
- Business-flow monitoring and runbooks are in place before launch.
- The three-year TCO includes people, change, risk and exit.
- A named internal owner stays accountable after the partner has left.
Sources and further reading
- Google Search Central: JavaScript SEO basics ↗
- Google Search Central: E-commerce site structure ↗
- web.dev: Rendering on the Web ↗
- web.dev: Web Vitals ↗
- MACH Alliance: MACH Explained ↗
- Medusa documentation: Workflows ↗
- Medusa documentation: Events and subscribers ↗
- OWASP API Security Top 10 ↗
- PCI Security Standards Council: PCI DSS ↗
- Stripe API: Idempotent requests ↗