Skip to content

Headless E-Commerce Implementation with Next.js and Shopify: A Developer Guide

Step-by-step headless e-commerce with Next.js and Shopify: Storefront API credentials, Hydrogen scaffolding, GraphQL queries, cart mutations, Vercel deployment.

Comparison card: Headless E-Commerce Implementation with Next.js and Shopify: A Developer Guide

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

Diagram showing pixel art icons of a globe, shopping cart, phone, laptop, and t-shirt connected to various logos including
Credit: Shopify

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):

  1. Go to Settings > Apps and sales channels > Develop apps and click Create an app.
  2. Under Configuration, open Storefront API integration and enable these scopes: unauthenticated_read_product_listings, unauthenticated_read_product_inventory, unauthenticated_write_checkouts, and unauthenticated_read_selling_plans.
  3. Click Save, navigate to API credentials, and click Install app to generate the access token.
  4. Copy the public access token. Note your store domain in the form mystore.myshopify.com.
  5. Create a .env.local file 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)

  1. 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.
  2. Provide the store domain and access token when prompted, or add them to the generated .env file.
  3. Confirm the project structure: app/ (Remix routes), app/components/, app/lib/ (API client), and public/.

Path B: Bare Next.js App Router (Vercel-compatible)

  1. Run npx create-next-app@latest --app to scaffold a project with the App Router enabled.
  2. Install the Shopify API client: npm install @shopify/storefront-api-client.
  3. Create lib/shopify.js and instantiate the client with the environment variable credentials from Step 1.
  4. Confirm the project structure: app/ (App Router pages and layouts), components/, lib/, and public/.

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:

PatternGraphQL OperationNext.js LocationCaching Strategy
Product collection listingproducts() queryapp/collections/[handle]/page.jsxStatic generation with ISR revalidation
Single product detailproduct(handle:) queryapp/products/[handle]/page.jsxSSR per request
Cart readcart(id:) queryClient component via hookNo CDN cache (user-specific)
Checkout URLcheckoutCreate mutationServer actionNo 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.

  1. cartCreate: call this when the user adds the first item. Returns a cart object containing id, checkoutUrl, and the initial lines array. Store the cart id in a browser cookie or localStorage. All subsequent cart mutation calls reference this id.
  2. cartLinesAdd(cartId, lines): adds items to an existing cart. Pass the stored cart id and an array of line items (each with merchandiseId and quantity). Returns the updated cart with recalculated cost.
  3. cartLinesUpdate(cartId, lines): changes quantity or swaps variant on an existing line item. Pass the line item id returned from a prior cartLinesAdd call.

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

  1. Connect the GitHub repository to a Vercel project via the dashboard or run vercel deploy from the CLI.
  2. In Project Settings > Environment Variables, add NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN and NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN.
  3. Vercel's build system detects the App Router and configures edge functions for SSR automatically.
  4. 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

  1. From the Hydrogen project root, run Hydrogen deploy.
  2. The CLI authenticates against the Shopify Partner account, builds the project, and deploys to Cloudflare Workers via the Oxygen runtime.
  3. 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:

DimensionVercel Edge NetworkShopify Oxygen
Compatible project typesAny Next.js projectHydrogen (Remix) only
Cost modelFree tier; usage-based aboveIncluded with Shopify Advanced or Plus
CDN providerVercel EdgeCloudflare Workers
Environment variablesVercel project settingsShopify Partner Dashboard
ISR / cache controlConfigured in Next.js route codeConfigured 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

Standards refs: NIST SP 800-204C API security; IETF RFC 8446 TLS 1.3.

See also IETF RFC 7159 JSON.

Share this guide

Amara Okeke

Amara Okeke edits techshooked's cloud and web-hosting coverage, from managed services and pricing to outages and architecture trade-offs. Her standard is operator-first: read the pricing page closely, weigh the migration and integration cost, and trust a benchmark only when the method behind it is clear.