Modern, open-source headless storefront for WooCommerce — built with Nuxt 4 & GraphQL.
Pinterest-style UI, dark mode, multi-language, and a DX focused, production-ready setup.
🚀 Live Demo
- Features
- Tech Stack
- Quickstart
- Configuration
- WordPress + WooCommerce + WPGraphQL Setup
- Architecture Overview
- API Endpoints (Server)
- Internationalization (i18n)
- Performance & Caching
- Contributors & Acknowledgements
- Contact
- 🎯 Headless WooCommerce store powered by WPGraphQL (+ WooGraphQL)
- ⚡️ Nuxt 4 + Nitro with server-side GraphQL proxy, SWR caching & route rules
- 🧭 Pinterest-style product grid with infinite scroll
- 🛒 Cart & Checkout (WooCommerce session cookie handled server-side)
- ❤️ Wishlist (localStorage) & Favorites page
- 🌙 Dark mode + sleek micro-interactions (skeletons, transitions)
- 🌐 Multi-language (en, nb, nl, de) via
@nuxtjs/i18n - 🖼️ Optimized images with
@nuxt/image - 🔔 Friendly toasts with Notivue
- 🔎 Good SEO defaults + JSON-LD Product schema
- ☁️ Ready for NuxtHub / Cloudflare Workers (KV cache)
- Framework: Nuxt 4, Vue 3
- GraphQL Client (server):
graphql-requestvianuxt-graphql-request - Styling/UI: Tailwind CSS,
@nuxt/ui, Icons (Iconify) - Images:
@nuxt/image - i18n:
@nuxtjs/i18n - Toasts:
notivue - Deployment (optional): NuxtHub + Cloudflare Workers
Project scripts live in
package.json(dev,dev:ssl,build,generate,preview,deploy).
- Node.js
>= 18.20(or 20.x) - pnpm (project uses
[email protected]) - A WordPress backend with WooCommerce + WPGraphQL (see setup below)
git clone https://github.com/zackha/nuxtcommerce.git
cd nuxtcommerce
pnpm installCreate .env:
GQL_HOST=https://your-woocommerce-site.com/graphqlpnpm run dev
# optional HTTPS local dev
pnpm run dev:sslApp runs at http://localhost:3000
pnpm run build
pnpm run previewKey settings are in nuxt.config.ts:
- Runtime Config:
runtimeConfig.gqlHost(readsGQL_HOST) - Modules:
@nuxt/ui,@nuxt/image,@nuxtjs/i18n,nuxt-graphql-request,notivue/nuxt,@nuxthub/core - Route Rules: SWR caching for
/categoriesand/favorites, prerender for/ - Nitro Prerender:
/sitemap.xml,/robots.txt - NuxtHub Cache:
hub: { cache: true }(optional KV cache)
This project uses WordPress + WooCommerce as the headless backend and WPGraphQL (+ WooGraphQL) as the API layer consumed by the Nuxt app. Follow the steps below carefully.
-
Install WordPress on your host (or local with e.g. Local, MAMP, Docker).
-
Log in to
/wp-admin. -
Go to Settings → General and set:
- Site Language, Timezone, Date/Time format
- Ensure WordPress Address and Site Address use https:// in production
-
Go to Settings → Permalinks and choose Post name.
Pretty permalinks are required for
/graphql.
Install and activate:
- WooCommerce – core e-commerce
- WPGraphQL – GraphQL API for WordPress
- WPGraphQL WooCommerce (WooGraphQL) – WooCommerce schema for WPGraphQL
- (Optional) Regenerate Thumbnails – rebuild image sizes after changes
- General: Store address, selling/shipping regions, currency (NOK/EUR/USD…)
- Products: Reviews on/off, measurements
- Tax: Enable and define rates (if applicable)
- Shipping: Create at least one zone + method (e.g., Flat rate)
- Payments: Enable Cash on Delivery (COD) for quick E2E testing
- Accounts & Privacy: Decide guest checkout
- Advanced: REST is not required; GraphQL is separate
Demo checkout posts
paymentMethod: 'cod'— ensure COD is enabled for testing.
Create attributes in Products → Attributes:
- Color (
slug: color→ taxonomypa_color) → used viaallPaColor - Style (
slug: style→ taxonomypa_style) → used viaallPaStyle
Add terms (e.g., Color: Red/Blue/Black; Style: Casual/Sport).
CSV Import (recommended for demo)
-
Download
public/products.zipfrom the repo. -
Products → Import, upload CSV(s), map columns:
- variable for parent products
- Attributes →
pa_color,pa_style. - Variations CSV must reference correct parent
-
Ensure products are Published, In Stock, with prices.
Manual
- Variable product → add attributes (used for variations) → create variations from attributes → set price/stock → set images.
Frontend queries use:
WOOCOMMERCE_THUMBNAILLARGE
Check sizes in WooCommerce (thumbnails) & Settings → Media (large). If you tweak sizes or bulk import images, run Regenerate Thumbnails.
Create .env in the Nuxt project:
GQL_HOST=https://your-woocommerce-site.com/graphqlThis is read by runtimeConfig.gqlHost and used by the server utility that proxies & caches GraphQL calls.
/app
├─ app.vue # Global head/meta + header/footer + Notivue
├─ app.config.ts # Site name/description, UI theme
├─ pages/
│ ├─ index.vue # Product grid, infinite scroll, filters
│ ├─ categories.vue # Category grid
│ ├─ favorites.vue # Wishlist page
│ └─ product/[id].vue # Product detail, gallery, variations, schema.org
├─ components/ # UI building blocks (cards, carousels, cart, checkout...)
├─ composables/ # useCart, useCheckout, useWishlist, useComponents
└─ gql/ # GraphQL queries & mutations
/server
├─ api/
│ ├─ products.get.ts # GET products (cursor pagination) — cached (SWR)
│ ├─ product.get.ts # GET product detail — cached (SWR)
│ ├─ search.get.ts # GET search (top 6) — cached (SWR)
│ ├─ categories.get.ts # GET categories — cached (SWR)
│ ├─ cart/add.post.ts # POST add to cart (Woo session cookie handling)
│ ├─ cart/update.post.ts # POST update quantities / remove
│ └─ checkout.post.ts # POST checkout (COD demo)
├─ routes/
│ ├─ sitemap.xml.ts # Minimal sitemap
│ └─ robots.txt.ts # Robots
└─ utils/wpgraphql.ts # GraphQL client + error wrapper + Woo session cookie
Flow:
Client ($fetch to /api/*) → Nitro server proxies to WPGraphQL → GET endpoints are cached (SWR); POST endpoints manage the WooCommerce session cookie.
GET /api/products?search=&category=&orderby=DESC|ASC&fieldby=DATE|PRICE&after=...GET /api/product?slug=:slug&sku=:skuFragmentGET /api/search?search=:q(first 6)GET /api/categoriesPOST /api/cart/add{ productId }POST /api/cart/update{ items: [{ key, quantity }] }POST /api/checkout{ billing: {...}, paymentMethod: 'cod' }
- Locales: en-GB, nb-NO, nl-NL, de-DE
- Default: en
- Use
useLocalePath()for links; SEO tags adapt per route.
cachedEventHandleron GET handlers with SWR (stale-while-revalidate)- Route Rules for
/categoriesand/favorites - Optional NuxtHub KV cache (
hub: { cache: true }) - Image optimization via
@nuxt/image - Prerender:
/,/sitemap.xml,/robots.txt
We sincerely thank everyone who has contributed to NuxtCommerce. Your support, feedback, and ideas keep this project moving forward. 🚀
✨ Special thanks
| Collaborator |
|---|
@rikp777 |
More contributors will be highlighted here as the project grows.
Have questions or suggestions?
- Email: [email protected]
- X (Twitter): @ZHatlen
Note
You can view the orders you create during the live demo at NuxtCommerce Admin.
From there, you can also update their statuses and add notes to your orders.