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-request
vianuxt-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
pnpm@10.x
) - A WordPress backend with WooCommerce + WPGraphQL (see setup below)
git clone https://github.com/zackha/nuxtcommerce.git
cd nuxtcommerce
pnpm install
Create .env
:
GQL_HOST=https://your-woocommerce-site.com/graphql
pnpm run dev
# optional HTTPS local dev
pnpm run dev:ssl
App runs at http://localhost:3000
pnpm run build
pnpm run preview
Key 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
/categories
and/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.zip
from 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_THUMBNAIL
LARGE
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/graphql
This 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=:skuFragment
GET /api/search?search=:q
(first 6)GET /api/categories
POST /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.
cachedEventHandler
on GET handlers with SWR (stale-while-revalidate)- Route Rules for
/categories
and/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: zckhtln@icloud.com
- 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.