A headless e-commerce implementation is a developer procedure that connects a Next.js frontend to Shopify's Storefront API, replacing Shopify's default Liquid template engine with a custom React application served from a CDN edge.
The commerce engine stays intact. Shopify continues to own inventory, orders, payments, and fulfillment. What changes is the presentation layer: a decoupled frontend built on Next.js handles page rendering, routing, and UI, while the API (Shopify's GraphQL storefront interface) feeds it product catalog, cart state, and checkout URLs. That separation lets frontend teams ship independently of Shopify's release cycle and gives the storefront access to the full React ecosystem.
The procedure covers credential setup, project scaffolding via Shopify Hydrogen, GraphQL query construction, cart operations, and deployment to either Vercel or Shopify Oxygen hosting. Estimated time is four hours for a developer familiar with React.
What a Headless E-Commerce Implementation with Next.js and Shopify Involves

The architecture splits into two independent runtime environments. Shopify manages inventory, orders, payments, and fulfillment on the backend. A decoupled frontend built on Next.js queries Shopify for product catalog data, cart state, and checkout initiation. Neither layer substitutes for the other.
Shopify Hydrogen is Shopify's official React-based framework for building a custom storefront. It ships pre-built React components (CartProvider, ShopifyProvider, MediaFile) and a useCart() hook that reduces the boilerplate required to wire cart state. Hydrogen runs on Remix conventions. Teams that prefer Next.js file-based routing and React Server Components can call the API client library directly without Hydrogen, at the cost of more scaffolding code. For the architecture decision that precedes this procedure, see headless ecommerce systems.
Before starting, confirm you have the following prerequisites:
- Node.js at the current LTS release
- A Shopify Partner account or development store with storefront access enabled in the Shopify admin
- A Vercel account (for Next.js deployment) or a Shopify account with Oxygen access (for Hydrogen deployment)
- Git and a code editor
The scalable infrastructure patterns behind custom storefront architecture are covered in the hub guide on building scalable online stores.
Step 1: Configure Shopify Storefront API Credentials
A headless e-commerce implementation cannot make a single API call without valid Shopify Storefront API credentials: the store domain and a public access token scoped to read-only storefront operations. The Admin API key is a separate credential and must never appear in frontend code.
Follow these steps to generate both values in the Shopify admin (Shopify API documentation):
- Go to Settings > Apps and sales channels > Develop apps and click Create an app.
- Under Configuration, open Storefront API integration and enable these scopes:
unauthenticated_read_product_listings,unauthenticated_read_product_inventory,unauthenticated_write_checkouts, andunauthenticated_read_selling_plans. - Click Save, navigate to API credentials, and click Install app to generate the access token.
- Copy the public access token. Note your store domain in the form
mystore.myshopify.com. - Create a
.env.localfile at the project root and add these two variables:NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN=mystore.myshopify.com NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN=your_public_token_here
The public access token is safe to expose in client-side bundles because it is scoped to read-only storefront data. A custom storefront cannot modify inventory, orders, or customer records through it. For scope details and token rotation procedures, consult the official Shopify documentation linked above.
Step 2: Scaffold the Next.js Project with Shopify Hydrogen
A headless e-commerce implementation needs a project scaffold before any product data can be fetched. Two paths are available depending on which routing convention the team prefers.
Path A: Shopify Hydrogen CLI (Remix-based, Oxygen-compatible)
- Run
npm create @shopify/hydrogen@latest. The CLI scaffolds a React Router project with the API pre-wired, Tailwind CSS configured, and Oxygen deployment hooks included. - Provide the store domain and access token when prompted, or add them to the generated
.envfile. - Confirm the project structure:
app/(Remix routes),app/components/,app/lib/(API client), andpublic/.
Path B: Bare Next.js App Router (Vercel-compatible)
- Run
npx create-next-app@latest --appto scaffold a project with the App Router enabled. - Install the Shopify API client:
npm install @shopify/storefront-api-client. - Create
lib/shopify.jsand instantiate the client with the environment variable credentials from Step 1. - Confirm the project structure:
app/(App Router pages and layouts),components/,lib/, andpublic/.
The Shopify Hydrogen component library (CartProvider, ShopifyAnalytics, Image) is framework-agnostic. Teams on Path B can import these components by installing @shopify/hydrogen-react separately. The Hydrogen CLI creates a Remix project by default; choosing Path B trades Oxygen compatibility for Next.js App Router routing and React Server Components. Source: Shopify Hydrogen documentation and Next.js App Router documentation.
Step 3: Fetch Product Data with GraphQL Queries
A headless e-commerce implementation needs two primary GraphQL query patterns to render a working storefront: a product collection query for catalog pages, and a single-product query for detail pages. Both run as server-side rendering operations in App Router server components.
The product collection query fetches a list of products for a collection or catalog page. A minimal example:
const PRODUCTS_QUERY = `
query ProductCollection($handle: String!, $first: Int!) {
collection(handle: $handle) {
products(first: $first) {
edges {
node {
id
title
handle
priceRange {
minVariantPrice { amount currencyCode }
}
featuredImage { url altText }
variants(first: 5) {
edges {
node { id title availableForSale }
}
}
}
}
}
}
}
`;Place this GraphQL query in an async server component at app/collections/[handle]/page.jsx. Because the component runs on the server, the access token never reaches the client bundle even when the environment variable uses the NEXT_PUBLIC_ prefix.
The single-product query fetches a product by handle for the detail page at app/products/[handle]/page.jsx. Add description, seo (title, description), options (name, values), and all variant combinations to the field selection. Server-side rendering of product pages produces fully-rendered HTML before it reaches the browser, which directly improves Largest Contentful Paint scores for product hero images. The Vercel Edge Network caches those rendered pages at the nearest point of presence.
The table below maps each query pattern to its Next.js location and caching strategy:
| Pattern | GraphQL Operation | Next.js Location | Caching Strategy |
|---|---|---|---|
| Product collection listing | products() query | app/collections/[handle]/page.jsx | Static generation with ISR revalidation |
| Single product detail | product(handle:) query | app/products/[handle]/page.jsx | SSR per request |
| Cart read | cart(id:) query | Client component via hook | No CDN cache (user-specific) |
| Checkout URL | checkoutCreate mutation | Server action | No cache |
For the full product object schema and all available query fields, consult the Shopify Storefront API GraphQL reference. The architectural context for why server-side rendering matters in headless commerce is covered in the headless ecommerce systems guide.
Step 4: Implement Cart State with Storefront API Mutations
A headless e-commerce implementation requires explicit cart state management because the Shopify-managed cart UI is unavailable in a custom storefront. Cart state is user-specific and cannot be CDN-cached, making it the most operationally distinct part of the build. Three cart mutation operations cover the full lifecycle.
Use Next.js Server Actions to invoke each cart mutation. Server Actions are server-side functions callable from client components without a separate API route; they keep mutation logic and the access token out of the client bundle entirely.
- cartCreate: call this when the user adds the first item. Returns a cart object containing
id,checkoutUrl, and the initiallinesarray. Store the cartidin a browser cookie or localStorage. All subsequent cart mutation calls reference thisid. - cartLinesAdd(cartId, lines): adds items to an existing cart. Pass the stored cart
idand an array of line items (each withmerchandiseIdandquantity). Returns the updated cart with recalculatedcost. - cartLinesUpdate(cartId, lines): changes quantity or swaps variant on an existing line item. Pass the line item
idreturned from a priorcartLinesAddcall.
Teams using Hydrogen toolkit can replace manual wiring with the CartProvider component. CartProvider wraps the application in a React context and handles cartCreate and cartLinesAdd internally. Any client component in the tree calls useCart() to read or trigger mutations without touching the API layer directly. The full cart mutation schema is in the Hydrogen documentation.
Step 5: Deploy the Decoupled Frontend to Vercel or Oxygen
A headless commerce implementation reaches production through one of two targets: the Vercel Edge Network for Next.js App Router projects, or Shopify Oxygen hosting for Hydrogen projects. The choice is fixed by the scaffolding path selected in Step 2.
Deployment A: Vercel Edge Network
- Connect the GitHub repository to a Vercel project via the dashboard or run
vercel deployfrom the CLI. - In Project Settings > Environment Variables, add
NEXT_PUBLIC_SHOPIFY_STORE_DOMAINandNEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN. - Vercel's build system detects the App Router and configures edge functions for SSR automatically.
- For collection pages using static generation, set an ISR revalidation interval in the route file:
export const revalidate = 60. Product detail pages with live inventory should use SSR rather than ISR to prevent serving stale availability data.
Deployment B: Shopify Oxygen Hosting
- From the Hydrogen project root, run
Hydrogen deploy. - The CLI authenticates against the Shopify Partner account, builds the project, and deploys to Cloudflare Workers via the Oxygen runtime.
- Environment variables for the deployed storefront are managed in the Shopify Partner Dashboard, not in Vercel project settings.
Oxygen hosting is included at no additional cost with Shopify Advanced and Shopify Plus plans. Vercel operates on a free tier with usage-based pricing above it. Teams on the bare App Router path must use Vercel or another Node.js-compatible host. The table below summarizes key operational differences:
| Dimension | Vercel Edge Network | Shopify Oxygen |
|---|---|---|
| Compatible project types | Any Next.js project | Hydrogen (Remix) only |
| Cost model | Free tier; usage-based above | Included with Shopify Advanced or Plus |
| CDN provider | Vercel Edge | Cloudflare Workers |
| Environment variables | Vercel project settings | Shopify Partner Dashboard |
| ISR / cache control | Configured in Next.js route code | Configured in Remix loader cache headers |
For ISR configuration options and edge function behavior, see the Vercel deployment documentation. For the Oxygen CLI deploy workflow and Cloudflare Workers runtime constraints, see the Hydrogen documentation. The W3C Payment Request API specification (W3C TR/payment-request) governs browser-native payment experiences (Apple Pay, Google Pay) that headless checkout flows can invoke through either deployment target.
Further reading
- Shopify API reference , complete GraphQL query and mutation schema
- Hydrogen documentation , CLI scaffolding, CartProvider, Oxygen deploy workflow
- Next.js documentation , async server components, Server Actions, ISR configuration
- Vercel deployment documentation , environment variables, edge functions, cache behavior
- Building scalable online stores , cloud architecture patterns for high-volume e-commerce
- How to Choose a CDN Alternative to AWS CloudFront
- Route 53 vs Cloudflare: DNS Management Comparison
Standards refs: NIST SP 800-204C API security; IETF RFC 8446 TLS 1.3.
See also IETF RFC 7159 JSON.









