ShopifyNext.jsE-commerceGraphQL

Headless Shopify with Next.js and the Storefront API

How to build a fully headless Shopify storefront using Next.js, GraphQL, and the Storefront API — with ISR product pages, a real-time cart, and a 95+ Lighthouse score.

Deepak Kaushal··11 min read

Shopify is the world's best commerce backend — battle-tested inventory, reliable checkout, and a mature ecosystem of apps. But default storefront themes are a constraint. Headless Shopify lets you keep the backend you trust while building any frontend experience you want in React and Next.js.

The Shopify Storefront API

The Storefront API is a public GraphQL API that exposes everything a storefront needs: products, collections, customers, carts, and checkout. You query it from your Next.js app — in Server Components for static content like product pages, or in client-side hooks for interactive operations like cart management. All you need is a Storefront API access token, available free from the Shopify admin.

Setting Up the GraphQL Client

A lightweight fetch-based GraphQL client works well for most headless Shopify setups. It keeps your bundle lean and gives you full control over caching behaviour — including Next.js's native fetch caching and revalidation.

// lib/shopify.js
const endpoint = `https://${process.env.SHOPIFY_STORE_DOMAIN}/api/2025-01/graphql.json`;

export async function shopifyFetch(query, variables = {}, options = {}) {
  const res = await fetch(endpoint, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Shopify-Storefront-Access-Token': process.env.SHOPIFY_STOREFRONT_TOKEN,
    },
    body: JSON.stringify({ query, variables }),
    next: { revalidate: options.revalidate ?? 60 },
  });
  if (!res.ok) throw new Error(`Shopify fetch failed: ${res.status}`);
  return res.json();
}

Product Pages with Incremental Static Regeneration

Product pages are the perfect ISR use case. At build time, generate the top-selling products statically. For new products, generate on first request and cache with a 60-second revalidation so price and inventory stay current. The result is pre-rendered HTML served from Vercel's CDN edge — no server processing, no JavaScript execution needed to see the product — Lighthouse scores consistently above 95.

// app/products/[handle]/page.js
export async function generateStaticParams() {
  const { data } = await shopifyFetch(
    `query { products(first: 250) { nodes { handle } } }`
  );
  return data.products.nodes.map((p) => ({ handle: p.handle }));
}

export const revalidate = 60;

export default async function ProductPage({ params }) {
  const { data } = await shopifyFetch(PRODUCT_QUERY, { handle: params.handle });
  if (!data.product) notFound();
  return <ProductDetail product={data.product} />;
}

Cart Management with the Cart API

Shopify's Cart API is the right choice for modern headless stores. Create a cart on first add-to-cart, persist the cart ID in a cookie, and all subsequent add/remove/update operations are mutations against that cart ID. The cart state lives in Shopify — you never need to sync it to your own database.

const CREATE_CART = `
  mutation cartCreate($input: CartInput!) {
    cartCreate(input: $input) {
      cart {
        id
        checkoutUrl
        lines(first: 20) {
          nodes {
            id
            quantity
            merchandise {
              ... on ProductVariant {
                title
                price { amount currencyCode }
                product { title featuredImage { url } }
              }
            }
          }
        }
        cost { totalAmount { amount currencyCode } }
      }
    }
  }
`;

Checkout Redirect

When the customer is ready to purchase, redirect to cart.checkoutUrl — a Shopify-hosted checkout page. You never handle payment details, and you get Shopify's battle-tested checkout with all payment methods, shipping calculations, and discount codes built in. After purchase, Shopify redirects back to your thank-you page URL.

Collection Pages and Filtering

The Storefront API supports filtering via product metafields, variant options, price ranges, and availability. Build collection pages with server-side filtering by passing filter params to the products query. For real-time count updates as users select filters, fetch filtered results client-side with a debounced query. For catalogues above 10,000 SKUs, Algolia or Shopify Search & Discovery provides faster relevance and typo tolerance.

Customer Accounts

For customer accounts in a headless store, use Shopify's hosted Customer Account API. Your store redirects to Shopify's OAuth login page, the customer authenticates, and Shopify redirects back with an access token. This keeps you out of the business of handling passwords and session management directly — the safest approach for any production store.

SEO with Product Schema

Headless Next.js gives you full control over SEO. Generate metadata dynamically from product data using Next.js generateMetadata. Add JSON-LD Product schema to every product page — this enables rich results in Google search showing price, availability, and reviews directly in the SERP. Use next/image for all product images: automatic WebP conversion, correct sizing, and lazy loading eliminates the largest image performance bottleneck in most storefronts.

International Markets

Shopify Markets lets you serve different prices and currencies per country. In a headless setup, pass the buyer's country in the @inContext directive on Storefront API queries — prices, availability, and the checkout flow localise automatically. Detect country from Vercel's geo headers or let the customer choose. Store the market context in a cookie and apply it to all queries for the session.

Real-World Performance Results

In a recent project, migrating from a Shopify Dawn theme to a custom Next.js headless frontend improved Lighthouse performance from 48 to 96. Mobile page load dropped from 4.2s to 1.1s. Mobile conversion rate increased 34% in the first quarter post-launch. The gains come from eliminating theme JavaScript overhead, serving pre-rendered HTML with ISR, and leveraging Vercel's CDN edge cache.

Further Reading

Frequently Asked Questions

Is headless Shopify worth it?

For stores with high traffic, complex UI requirements, or performance-critical markets, yes. Headless Shopify with Next.js can achieve Lighthouse scores of 95+ and sub-1.5s LCP. For smaller stores that work well with Liquid themes, the added complexity may not be justified.

What is the difference between Shopify Hydrogen and headless Next.js?

Shopify Hydrogen is a Remix-based framework built specifically for headless Shopify. Headless Next.js with the Storefront API gives you more flexibility and a wider ecosystem. Hydrogen is faster to start but more opinionated. Next.js gives you full control and a larger community.

Does headless Shopify still use Shopify Checkout?

Yes. Even in a fully headless setup, checkout is handled by Shopify's hosted checkout page. You redirect to cart.checkoutUrl when the customer is ready to purchase. This is a good thing — Shopify checkout is PCI-compliant, battle-tested, and has an extremely high conversion rate.

Can I use the Shopify Storefront API for free?

The Storefront API is available on all Shopify plans. You create a Storefront API access token from the Shopify admin at no additional cost. API usage is not rate-limited in a way that affects typical storefront traffic.

How do I handle Shopify inventory in a headless store?

Inventory data is exposed on variant nodes in the Storefront API. For real-time inventory on product pages, set a short revalidation window (30–60 seconds on ISR). For cart operations, rely on Shopify's own cart validation — it prevents out-of-stock additions automatically.

Can I migrate from a Shopify theme to headless Next.js?

Yes. Migration means rebuilding the storefront layer while keeping all Shopify backend data intact — products, orders, and customers all stay in Shopify. Plan 6–12 weeks for a full migration depending on catalogue size and custom features.

How do I handle customer accounts in headless Shopify?

For headless customer auth, use Shopify's hosted Customer Account API — it handles login, registration, and password reset via OAuth. Your storefront redirects to Shopify's login page, the customer authenticates, and Shopify redirects back with an access token. This keeps you out of the business of handling passwords directly.

What Lighthouse score can I expect with headless Shopify Next.js?

A well-implemented headless Next.js Shopify storefront routinely scores 95–100 on Lighthouse Performance. The gains come from ISR (pre-rendered HTML served from CDN edge), next/image for automatic WebP and lazy loading, and zero Liquid theme JavaScript overhead.

More Articles

Need help with this?

I'm available for Sharetribe Flex, Shopify, Next.js, and AI integration projects.

Get In Touch