ARTICLE

Headless Adobe Commerce with Next.js: Architecture Patterns and Pitfalls

Headless Adobe Commerce with Next.js: Architecture Patterns and Pitfalls

Headless Adobe Commerce with Next.js as the frontend is a mature pattern in 2026, but the production-grade builds look meaningfully different from the example projects in blog posts. The difference is in the architecture decisions: how authentication is handled, how customer-specific data flows, how the cart and checkout work, how performance scales, and where the operational boundaries sit. Teams that copy patterns from headless tutorials without addressing these decisions consistently produce builds that work in staging and fall apart in production.

This piece walks through the architecture patterns Bemeir’s Adobe Commerce team uses for production headless builds, and the pitfalls that consistently catch teams new to the architecture. The framework below is the version that has held up across multi-million-dollar production stores; the patterns are practitioner-tested rather than theoretical.

The default architecture

A reasonable production architecture for headless Adobe Commerce + Next.js looks like:

Adobe Commerce backend. Standard Adobe Commerce installation handling admin, catalog, customer data, orders, integrations. Either Adobe Commerce Cloud or self-hosted on AWS with the standard infrastructure stack (RDS/Aurora, Redis, OpenSearch, Varnish).

GraphQL or REST as the data layer. Adobe Commerce ships a GraphQL API and a REST API. The GraphQL API is the more modern choice and what most new headless builds use. REST remains useful for admin-side operations and for some edge cases.

Next.js frontend. Server-side rendered (SSR) or incremental static regeneration (ISR) for page generation. Deployed on Vercel, AWS, or other Next-compatible infrastructure. Communicates with Adobe Commerce via GraphQL.

CDN in front of Next.js. CloudFront, Cloudflare, or Vercel’s built-in edge network for global distribution and caching.

Customer data and session state. Handled via Adobe Commerce customer tokens, stored in HTTP-only cookies or in a separate session store depending on the architecture.

Search. Either Adobe Commerce native search (via GraphQL) or a separate search service (Algolia, Klevu) for advanced search experiences.

This is the architecture that most production headless builds end up at. Variations exist (different deployment models, different data layer choices) but the pattern is consistent.

Decision 1: Page generation strategy

The first architectural decision is how Next.js generates each page.

Server-Side Rendering (SSR). Every request hits Next.js, which fetches data from Adobe Commerce and renders the page on the server. Fresh data on every request; higher load on the backend; slower TTFB without caching.

Static Site Generation (SSG). Pages are pre-built at deploy time. Fastest possible delivery but stale data unless rebuilds are frequent. Not viable for stores with frequently-changing inventory or pricing.

Incremental Static Regeneration (ISR). Pages are statically generated but revalidated on a configurable cadence. Fast delivery with bounded staleness. The right default for product detail pages and category pages on most stores.

Client-side rendering for personalized data. Customer-specific elements (cart, account, recommended products based on history) render client-side after page load. Avoids personalizing the SSR/ISR response.

The pattern most production builds converge on: ISR for product, category, and content pages with revalidation every 60-300 seconds; client-side rendering for customer-specific elements; SSR only for pages where ISR cannot work (highly personalized landing pages, checkout pages).

Decision 2: Cart and checkout architecture

The cart and checkout flow is where headless builds most often fail. The pattern that works:

Cart state lives in Adobe Commerce. The Adobe Commerce GraphQL API supports cart creation, line item management, and quote handling. The cart is the source of truth, not the frontend.

Frontend holds a cart token. When a guest user adds a product, the frontend creates a cart in Adobe Commerce and stores the cart token in a cookie or local storage. Subsequent cart operations reference the token.

Customer cart vs guest cart. When a customer logs in, the guest cart is merged into the customer cart server-side. The merge logic is in Adobe Commerce, not in Next.js.

Checkout uses the Adobe Commerce checkout API. Address, shipping method, payment method, and order placement all go through Adobe Commerce’s checkout endpoints. The Next.js frontend orchestrates the flow but does not own the data.

Payment processing through Adobe Commerce or directly with the processor. Adobe Commerce can act as the intermediary to payment providers (Stripe, Adyen, etc.) or the frontend can hit the payment provider directly with Adobe Commerce updating after. The first model is simpler; the second is faster but introduces complexity around order state coordination.

Decision 3: Authentication and customer data

Customer login on a headless build:

Adobe Commerce issues customer tokens via GraphQL. The frontend posts credentials to the customer token mutation; Adobe Commerce returns a customer token.

Token stored in HTTP-only cookie. The token should be HTTP-only and Secure to prevent XSS-based theft. Avoid local storage for the token.

Subsequent requests include the token. Customer-specific GraphQL queries (account info, order history, addresses, customer cart) include the token in the Authorization header.

Token refresh. Adobe Commerce customer tokens expire. The frontend needs to handle expiration gracefully, either by refreshing the token before expiry or by handling 401 responses cleanly.

Decision 4: Performance and caching

Caching is where headless builds either win or lose on performance.

GraphQL query caching at the CDN layer. Many GraphQL queries are cacheable (catalog data, category data, content data). Cache them at the CDN level with appropriate cache keys (locale, currency, customer group) to reduce backend load.

Per-request caching for customer-specific data. Cart, customer account, and other customer-specific data is not cacheable at the CDN. Optimize the queries themselves to be fast.

Adobe Commerce backend caching. Adobe Commerce full page cache and configuration cache still operate even in headless mode. Tune them as you would on a Luma or Hyvä build.

Next.js ISR cache tuning. The ISR revalidation interval is a per-page-type decision. Product pages with frequent inventory changes need shorter intervals; category pages with stable structure can have longer intervals.

Image optimization. Adobe Commerce image generation should be offloaded to a CDN-fronted image service or a Next.js Image component pointing at a fast image source. Inline Adobe Commerce image generation will demolish LCP.

Pitfalls that consistently catch teams

Six patterns that show up in headless builds that did not anticipate them:

Pitfall 1: The first GraphQL query is slow on cold caches. On a new ISR revalidation or on a CDN cache miss, the request goes all the way back to Adobe Commerce. If the underlying query is slow (joining many tables, EAV lookups, etc.), TTFB is poor. Mitigation: profile and optimize the GraphQL resolvers on the backend before relying on caching to mask slow queries.

Pitfall 2: Cart token loss on customer login. If the cart merge logic is not implemented correctly, customers lose their guest cart items when they log in. This is a conversion killer. Test the login flow with an item in the cart on every release.

Pitfall 3: Personalization in SSR breaks caching. Rendering customer-specific data in the SSR response means every response is personalized and cannot be cached. The fix is keeping personalization client-side or using cache keys that scope per-customer (which limits cache hit rates).

Pitfall 4: Checkout state desync. The cart in Adobe Commerce and the cart displayed in Next.js can drift if the frontend assumes its local state is authoritative. The Adobe Commerce cart is always the source of truth; the frontend should re-fetch on critical decisions.

Pitfall 5: SEO regressions vs the original Luma build. Default Next.js does not produce the metadata, structured data, and canonical tags that the Luma build provided. These need to be deliberately implemented in the Next.js routing layer; missing them is the most common cause of post-launch traffic loss.

Pitfall 6: Operational complexity outruns team capability. A headless build adds infrastructure layers (Next.js deployment, CDN configuration, GraphQL contract management) that the team has to operate. Teams without this DevOps maturity end up with builds that work for the launch and degrade over time.

When headless makes sense

Three merchant profiles where headless Adobe Commerce + Next.js is consistently the right call:

Brands with strong design and engineering teams. The headless pattern unlocks design freedom and engineering velocity that Liquid or Luma cannot match. Teams that can take advantage of this get value from the architecture.

Multi-frontend strategies. Merchants running multiple frontends (web, mobile app, kiosk, voice) benefit from headless because the backend serves all of them through APIs.

Performance-critical stores. With proper architecture, a headless Next.js + Adobe Commerce build can achieve LCP under 1.4s consistently. Stores where performance is a competitive advantage benefit from the architecture.

When headless does not make sense

Three merchant profiles where headless adds complexity without proportional benefit:

Standard requirements with strong Hyvä fit. A Hyvä-themed Adobe Commerce build hits 80% of the headless performance wins with much lower complexity. Most mid-market Adobe Commerce stores do better with Hyvä than with full headless.

Teams without modern frontend expertise. Operating a Next.js production deployment with the patterns above requires modern frontend chops. Teams without this expertise should not commit to headless.

Tight time-to-launch. A headless build is 1.5-2x the implementation effort of a comparable Hyvä build. Tight timelines favor Hyvä.

What good headless looks like in production

A well-built headless Adobe Commerce + Next.js store should have:

Metric Target
Mobile LCP (p75) Under 1.5s
Mobile TTFB (p75) Under 400ms
GraphQL cache hit rate Above 80% for catalog queries
Next.js ISR coverage Most pages on ISR with appropriate revalidation
SEO parity vs prior build All metadata, structured data, canonicals preserved
Deploy frequency At least weekly, often daily
Incident rate Comparable to or lower than Luma/Hyvä builds at the same scale

Bemeir builds headless Adobe Commerce when it fits and recommends Hyvä when that fits better. The decision is determined by the merchant’s actual requirements: brand and engineering capability, multi-frontend strategy, performance positioning, and operational maturity. The Adobe Commerce GraphQL documentation and Next.js documentation provide the building blocks; the framework above is what bridges them to a production-grade architecture. The work is well-understood; the variable is whether the team executes the right patterns or fights the architecture for two years before getting it right.

Let us help you get started on a project with Headless Adobe Commerce with Next.js: Architecture Patterns and Pitfalls and leverage our partnership to your fullest advantage. Fill out the contact form below to get started.

more articles about ecommerce

Read on the latest with Shopify, Magento, eCommerce topics and more.