80% off for waitlist membersJoin now and lock in Launch from $39.80 or Lifetime from $49.80 

← Back to Guides

Headless WooCommerce Tutorial: Build a Next.js Storefront

WPBundle Team··14 min read
headless woocommerce tutorialheadless woocommerce developmentheadless wordpress tutorialwoocommerce nextjs tutorial

This headless WooCommerce tutorial walks you through building a decoupled storefront step by step. No theory-heavy introductions — we assume you know what headless means and want to start building. By the end, you will have a Next.js frontend connected to WooCommerce's REST API, rendering products, handling cart state, and ready for checkout integration.

TL;DR

Set up WooCommerce with API credentials, scaffold a Next.js project, fetch products via the REST API, build product listing and detail pages with ISR, implement client-side cart state, and connect a checkout flow. The tutorial covers each step with the key decisions and gotchas. Estimated time: 2-4 days for a working prototype.

Prerequisites

Before starting your headless WooCommerce development project, you need:

  • A WordPress installation with WooCommerce activated and products added
  • Node.js 20+ installed locally
  • Basic React and Next.js knowledge (components, hooks, data fetching)
  • Familiarity with REST APIs (fetch, async/await)
  • A code editor and terminal

Your WooCommerce store can be local (LocalWP, MAMP) or hosted. For development, local is faster. For production, you will need a hosted WordPress instance — see our best WooCommerce hosting guide for options.

Step 1: Configure WooCommerce API access

WooCommerce includes a REST API out of the box. You need to generate API credentials and configure your WordPress installation for headless use.

Generate API keys

In your WordPress admin, go to WooCommerce → Settings → Advanced → REST API. Click “Add key” and create a key with Read/Write permissions. Save the Consumer Key and Consumer Secret — you will need both for API authentication.

Enable pretty permalinks

The WooCommerce REST API requires pretty permalinks. Go to Settings → Permalinks and select any option other than “Plain.” Post name (/%postname%/) is the most common choice.

Handle CORS

If your Next.js frontend and WordPress backend run on different domains (they will in production), you need to allow cross-origin requests. Add CORS headers to your WordPress installation via a plugin or a small snippet in functions.php. Alternatively, proxy API requests through Next.js API routes to avoid CORS entirely — this is the approach WPBundle uses and it is more secure because your WooCommerce credentials never reach the browser.

Never expose API keys to the client

WooCommerce consumer keys and secrets should only be used in server-side code (Next.js API routes, server components, or getServerSideProps). If they reach the browser, anyone can read and write your store data. Use environment variables and server-side fetching exclusively.

Step 2: Scaffold your Next.js project

Create a new Next.js project with the App Router. The App Router is the recommended architecture for new Next.js projects and provides server components, streaming, and better data fetching patterns.

Run npx create-next-app@latest my-store and select TypeScript, Tailwind CSS, and the App Router when prompted. Add your WooCommerce credentials as environment variables in .env.local:

  • WORDPRESS_URL — your WordPress site URL (e.g. https://your-store.com)
  • WC_CONSUMER_KEY — the consumer key from step 1
  • WC_CONSUMER_SECRET — the consumer secret from step 1

Create a WooCommerce API utility

Build a reusable fetch wrapper that handles authentication and error handling. This utility should construct the full API URL, append authentication parameters, and return typed JSON responses. The WooCommerce REST API base path is /wp-json/wc/v3/. For a deeper dive into the API structure, see our WooCommerce REST API + Next.js guide.

Step 3: Build the product listing page

Your shop page fetches products from the WooCommerce API and renders them as a grid. Using a React Server Component, the data fetching happens on the server — no client-side loading spinners needed.

Fetching products

Call /wp-json/wc/v3/products with parameters for pagination, category filtering, and ordering. The API returns product objects with name, price, images, categories, and more. Key parameters to use: per_page (default 10, max 100), page for pagination, category for filtering, and orderby for sorting.

Rendering the grid

Map over the products array and render a card component for each. Use Next.js Image component for product images — it handles lazy loading, responsive sizing, and WebP conversion automatically. Link each card to /products/[slug] for the detail page.

Pagination

The WooCommerce API returns total product count and page count in response headers (X-WP-Total and X-WP-TotalPages). Use these to build pagination controls. For SEO, use URL-based pagination (/shop?page=2) rather than client-side state so each page is indexable.

100

Max products per API request

<200ms

API response time with object caching enabled

ISR

Incremental Static Regeneration for automatic page updates

Step 4: Build the product detail page

Each product gets its own page at /products/[slug]. This page fetches a single product by slug and renders the full product experience: images, title, price, description, variations (if variable), and an add-to-cart button.

Static generation with ISR

Use generateStaticParams to pre-build product pages at deploy time. Fetch all product slugs and return them as params. Enable ISR with a revalidation period (e.g. 60 seconds) so pages update automatically when product data changes in WooCommerce — without rebuilding the entire site.

Variable products

WooCommerce variable products (sizes, colours) require fetching variations via /products/{id}/variations. Each variation has its own price, stock status, and image. Build a client component that lets customers select attributes and updates the displayed price and image accordingly. This is one of the more complex parts of a headless WooCommerce build — see our variable products guide for performance considerations.

Product images

WooCommerce returns image URLs from your WordPress media library. Configure Next.js next.config.js to allow images from your WordPress domain. Use the Image component with sizes and priority props for the main product image (above the fold) and lazy loading for gallery images.

SEO for product pages

Each product page needs a unique title tag, meta description, Open Graph tags, and JSON-LD Product schema (with price, availability, reviews). Generate these from the WooCommerce API data in your page metadata function. This is critical for Google Shopping and rich search results. See our headless WooCommerce SEO guide for the full checklist.

Step 5: Implement cart state

The cart is the hardest part of any headless WooCommerce build. In traditional WooCommerce, cart state lives in PHP sessions on the server. In a headless setup, you need a different approach.

Client-side cart (simplest)

Store cart state in React context or Zustand, persisted to localStorage. Products are added and removed entirely on the client. This is fast and simple but means the cart exists only in the browser — it does not sync with WooCommerce until checkout.

Server-synced cart (recommended for production)

Use WooCommerce's Store API (/wp-json/wc/store/v1/cart) or a plugin like CoCart to maintain cart state on the server. This ensures cart data persists across devices, respects server-side pricing rules (coupons, dynamic pricing), and keeps inventory accurate. The trade-off is API latency on every cart operation.

For a deep dive into cart session management, see our headless WooCommerce cart sessions guide.

Pros

  • Client-side cart: instant interactions, no API latency, works offline
  • Server-synced cart: accurate pricing, inventory checks, cross-device persistence

Cons

  • Client-side cart: no server-side pricing rules, no real-time inventory
  • Server-synced cart: API latency on every add/remove, more complex implementation

Step 6: Connect checkout

Checkout is where headless WooCommerce gets genuinely complex. You have three main options, each with different trade-offs.

Option 1: Redirect to WooCommerce checkout

The simplest approach. When the customer clicks “Checkout,” redirect them to your WordPress site's native checkout page. This uses WooCommerce's built-in checkout with all its payment gateways, tax calculation, and shipping logic. The downside: customers leave your fast headless frontend for a slower PHP-rendered page.

Option 2: Stripe Checkout (hosted)

Create a Stripe Checkout session from your Next.js API route, passing the cart items and prices. Stripe handles the entire checkout UI, payment collection, and PCI compliance on their hosted page. After payment, create the WooCommerce order via API. This is the fastest path to a working headless checkout. See our Stripe checkout integration guide.

Option 3: Custom checkout with Stripe Elements

Build a fully custom checkout form with address fields, shipping options, and Stripe Elements for payment. This gives you complete design control but requires implementing address validation, tax calculation, shipping rate fetching, and order creation yourself. This is the most work but produces the best customer experience. For the full architectural breakdown, see our headless checkout guide.

Start simple, upgrade later

For a prototype or MVP, use Stripe Checkout (Option 2). It takes hours to implement, not weeks. Once your store is live and generating revenue, invest in a custom checkout (Option 3) for maximum conversion optimisation. Premature checkout customisation is the most common time sink in headless WooCommerce projects.

Step 7: Deploy and go live

Deploy your Next.js frontend to Vercel, Netlify, or Cloudflare Pages. Vercel is the most seamless option for Next.js — zero configuration, automatic preview deployments, and edge caching built in.

  • Connect your Git repository to Vercel for automatic deployments
  • Add environment variables (WordPress URL, WooCommerce keys) in the Vercel dashboard
  • Configure your custom domain and SSL
  • Set up ISR revalidation webhooks so product changes trigger page updates
  • Test the full purchase flow end-to-end before switching DNS

For WooCommerce webhooks that trigger Next.js revalidation when products or orders change, see our WooCommerce webhooks + Next.js guide.

2-4 days

Time to build a working prototype

2-6 weeks

Time to build a production-ready store from scratch

<1 day

Time to deploy with WPBundle (pre-built storefront)

Common pitfalls

Underestimating the cart and checkout

Product listing and detail pages are the easy part — they are mostly read-only data display. The cart (state management, session persistence, pricing rules) and checkout (payment, tax, shipping, order creation) are where 70% of the development effort goes. Plan your timeline accordingly.

Ignoring WooCommerce API limitations

The WooCommerce REST API does not expose everything. Some data requires custom endpoints or the WPGraphQL plugin. Common gaps: advanced product filtering, real-time inventory, and complex shipping calculations. Check the API documentation for your specific requirements before committing to an architecture. For a comparison of API options, see our REST API vs WPGraphQL guide.

Skipping SEO implementation

A headless frontend that does not implement meta tags, structured data, canonical URLs, and sitemaps will lose search rankings. This is not optional — it must be built from the start, not bolted on later.

The 80/20 trap

Getting products to display on a Next.js page takes a few hours. Going from “products display” to “customers can buy things” takes weeks. Budget 80% of your development time for cart, checkout, SEO, and edge cases.

How WPBundle helps

This tutorial covers the fundamentals of headless WooCommerce development, but building a production-ready store from scratch takes weeks of work on cart sessions, checkout flows, payment integration, SEO, and API gaps. WPBundle provides all of this out of the box.

  • Complete Next.js storefront — product listing, detail pages, and category pages
  • Cart session management with server-side sync already implemented
  • Stripe payment integration with checkout flow included
  • Automatic SEO with JSON-LD, Open Graph, sitemaps, and meta tags
  • Companion WordPress plugin extending the REST API where needed
  • Edge-deployed on Vercel for sub-100ms global page loads

If you want to learn headless WooCommerce development, follow this tutorial. If you want a production store shipping this week, start with WPBundle and customise from there. Either way, your WooCommerce backend stays exactly where it is — only the frontend changes.

Ready to go headless?

Join the WPBundle waitlist and get beta access completely free.

Join the Waitlist