Headless Storefront (Next.js)
Run your shop on your own Next.js site while Joomni keeps your products, orders, payments and stock. Open source, free to use and change.
joomni225/joomni-nextjs-commerce
Clone the storefront and make it yours
Next.js 16, React 19 and Tailwind CSS 4. MIT licensed. No API key needed.
Prefer PHP?
Overview
What you get
A complete shop front you host yourself — on Vercel, your own server or anywhere Next.js runs. Everything you manage in the Joomni dashboard shows up on it, and every order lands back in Joomni.
Catalogue pages
Home, all products, search, collections and product pages with an image gallery and structured data for Google.
Option picker
Size and colour buttons that strike out sold-out combinations, on the product page and in a quick view from any product card.
Cart drawer
Opens after every add to cart. Quantities change in place; prices and stock are always read fresh.
Guest checkout
Shipping quoted from your zones, discount codes, cash on delivery and Scan & Pay — as set up in your store.
Order page
A bookmarkable page with progress, tracking numbers and the Scan & Pay form.
Instant updates
Edit a product in the dashboard and the page refreshes through a signed webhook.
Quick start
Run it in five minutes
You need Node.js 20.9 or newer and your store's subdomain. No API key: the starter reads the same public Storefront API your Joomni storefront uses.
Test orders are real orders
Architecture
How it works
- 1
Server-side only
Every call to Joomni runs in Server Components and Server Actions. The browser never talks to Joomni, so there is no CORS to set up. - 2
A cart without prices
The cart cookie holds product handles, variant ids and quantities. Prices and stock are read from the catalogue each time. - 3
Joomni has the final word
When an order is placed, Joomni re-prices it from the catalogue, re-quotes shipping and re-checks codes. Nothing in the browser can lower a total.
Webhooks
Instant updates
Pages are cached and refresh on their own after JOOMNI_REVALIDATE_SECONDS. Add a webhook and they refresh the moment you change something.
- 1
Deploy
Put the site on a public URL (a tunnel works for testing). - 2
Add the endpoint
In Settings › API & Webhooks › Webhooks, addhttps://your-site/api/webhooks/joomniforproducts/create,products/update,products/delete,inventory/level_update,orders/createandorders/cancelled. - 3
Add the secret
Copy thewhsec_…signing secret intoJOOMNI_WEBHOOK_SECRETand redeploy.
The route checks each delivery's signature against the raw body, ignores repeat deliveries and refreshes the matching pages. Webhooks aren't retried yet, so keep the timer on as a safety net. Signatures and topics are explained in REST API & Webhooks.
Make it yours
Where to change things
| To change | Edit |
|---|---|
| Colours, radius, dark mode | src/app/globals.css |
| Fonts and the announcement bar | src/app/layout.tsx |
| Header and footer links | Your main-menu and footer menus in Website › Navigation |
| Home page sections | src/app/page.tsx |
| Product cards | src/components/product-card.tsx |
| Cart drawer and option picker | src/components/cart-drawer.tsx, variant-modal.tsx |
| Checkout fields | src/components/checkout-form.tsx |
src/app/globals.csssrc/app/layout.tsxsrc/app/page.tsxsrc/components/product-card.tsxsrc/components/cart-drawer.tsx, variant-modal.tsxsrc/components/checkout-form.tsxRoadmap
Not included yet
Pull requests are welcome on GitHub.
- Customer accounts: checkout is guest-only. A store set to require sign-in shows a message instead.
- Custom checkout fields from your checkout settings.
- Automatic discounts (discount codes work).
- eSewa, Khalti and IME Pay: cash on delivery and Scan & Pay only.
- Blog posts and website pages from your Joomni theme.