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_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/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=: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.
- 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.
