A modern, type-safe headless ecommerce starter built with Thor Commerce, Next.js 16, React 19, TypeScript, and GraphQL.
Use this template · Thor Commerce · Developer documentation · Storefront API
This repository is a reference storefront for Thor Commerce, the unified commerce platform for B2B, DTC, and hybrid business models. It demonstrates real customer-facing commerce flows—from product discovery and market-aware pricing to cart, checkout, payments, orders, and customer accounts—using the Next.js App Router.
Use it as a starting point for a custom storefront, as an integration reference for the Thor Storefront GraphQL API, or as a working example of server-first commerce architecture in Next.js.
- Commerce primitives included. Catalog, variants, collections, categories, availability, pricing, discounts, cart, shipping, checkout, payments, orders, and accounts are already connected.
- Server-first and type-safe. React Server Components and Server Actions call typed GraphQL documents without exposing storefront credentials to the browser.
- Built for customization. Features are grouped by domain, styling uses local CSS Modules, and generated API types remain separate from handwritten application code.
- Market-aware by design. Country-prefixed routes resolve store and currency context before catalog or cart operations run.
- Deployable to the edge. OpenNext and Wrangler configuration is included for Cloudflare Workers with R2-backed incremental caching.
| Area | Included |
|---|---|
| Catalog | Product listings, product details, variants, categories, collections, sorting, faceted filters, and availability |
| Pricing | Store- and currency-aware prices, product discounts, cart discounts, and formatted money values |
| Cart | Cookie-backed persistence, quantity updates, line removal, availability checks, discount display, and cart totals |
| Checkout | Payment gateway selection, customer details, shipping methods, order summary, and order completion |
| Payments | Stripe Payment Element, wallets supported by Stripe, and manual payment gateways |
| Customer accounts | Registration, login, logout, password reset, customer sessions, and customer-aware pricing |
| Markets | Country-prefixed routing with store and currency context injected at the request boundary |
| Media | Responsive product images backed by Thor Commerce media URLs and image transformations |
| UI | React Aria components, responsive layouts, loading states, skeletons, drawers, and accessible controls |
| Deployment | Standard Next.js production builds for a Node.js server or a compatible hosting platform |
Browser
↓
Next.js routes, React Server Components, and Server Actions
↓
Country, store, currency, cart, and customer context
↓
Typed GraphQL operations through storefrontFetch
↓
https://api.thorcommerce.io/{THOR_PROJECT}/storefront/graphql
↓
Thor Commerce catalog, pricing, cart, checkout, and customer services
The browser receives rendered UI and invokes Server Actions. Storefront credentials and authenticated API calls stay on the server. GraphQL operations are authored in .graphql files and compiled into typed TypeScript documents with GraphQL Code Generator.
- Node.js 22.18 or newer
- pnpm
- A Thor Commerce project with Storefront API access
Start with the GitHub template or clone the repository:
git clone https://github.com/thor-commerce/next-thor-storefront.git
cd next-thor-storefront
pnpm installcp .env.example .envAdd your Thor project and application secrets to .env:
THOR_PROJECT="your-project-id"
THOR_STOREFRONT_API_KEY="your-storefront-api-key"
BETTER_AUTH_SECRET="generate-with-openssl-rand-base64-32"
BETTER_AUTH_URL="http://localhost:3000"
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY="generate-with-openssl-rand-base64-32"Keep secrets in local environment files or your deployment platform's secret store. Never commit real credentials.
pnpm codegenpnpm devOpen http://localhost:3000. The proxy redirects the request to a country-prefixed market route such as /dk.
Use .env.local for the sample store configuration, alongside your existing application secrets:
THOR_PROJECT="seed"
THOR_STOREFRONT_API_KEY="your-storefront-api-key"
NEXT_PUBLIC_THOR_STORE_ID="store_01m2na4m5jfsv94pw1tvvwv0cw"
THOR_PRICE_CHANNEL_ID="ch_01m2na4kynerzv51b8m029g34e"
NEXT_PUBLIC_THOR_CURRENCY="DKK"
NEXT_PUBLIC_THOR_MARKETS="dk,se,de"
BETTER_AUTH_URL="http://localhost:3000"Use a Storefront API key, not an Admin API key. The store and price channel IDs above belong to the current seed installation; use the corresponding IDs when installing the dataset in another project. Leave NEXT_PUBLIC_THOR_CHECKOUT_ORIGIN empty to use Thor's returned hosted checkout URL, including in .env.development.local, which takes precedence during development.
npm run dev -- --port 3000The footer market selector showcases Denmark (DKK), Sweden (SEK), and Germany (EUR). Set NEXT_PUBLIC_THOR_MARKETS to the allowed country codes. Switching markets preserves the current page, clears currency-dependent price filters, and reprices the cart without dropping items; unavailable items prevent the switch.
Open the seed catalog. Restart the dev server after changing environment variables. Public market settings are embedded at build time for production builds.
| Variable | Required | Purpose |
|---|---|---|
THOR_PROJECT |
Yes | Project ID used in the Thor Storefront GraphQL endpoint |
THOR_STOREFRONT_API_KEY |
Yes | Server-side credential sent with Storefront API requests |
BETTER_AUTH_SECRET |
Yes | Secret used to sign Better Auth state and sessions |
BETTER_AUTH_URL |
Yes | Base URL for authentication callbacks and cookies |
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY |
Production | Stable encryption key for Server Actions across deployments |
Edit src/lib/thorcommerce/config.ts to configure:
- supported country codes;
- the default country;
- Thor store IDs;
- supported currencies; and
- the mapping between markets, stores, and currencies.
src/proxy.ts resolves the country from the URL or the Cloudflare CF-IPCountry header, redirects invalid or missing market prefixes, and injects X-Thor-Country, X-Thor-Store, and X-Thor-Currency into the request.
Application requests are centralized in src/lib/thorcommerce/storefront/index.ts and sent to the project-specific endpoint:
https://api.thorcommerce.io/${THOR_PROJECT}/storefront/graphql
GraphQL source files live under src/lib/thorcommerce/storefront:
fragments/ Shared product, price, availability, cart, and money selections
queries/ Catalog, cart, checkout, order, and customer reads
mutations/ Cart, checkout, and customer writes
generated/ Generated TypeScript types and typed document strings
After changing a query, mutation, or fragment, regenerate the client:
pnpm codegenDo not edit generated/types.generated.ts manually. Update the GraphQL document and run code generation instead.
This map is intended for contributors, maintainers, and AI coding agents working in the repository.
| If you want to change… | Start here |
|---|---|
| Product queries and product pages | src/lib/thorcommerce/storefront/queries/products.graphql and src/features/products |
| Categories and collections | src/features/categories, src/features/collections, and their GraphQL queries |
| Cart behavior | src/features/cart and src/lib/thorcommerce/storefront/mutations/cart.graphql |
| Checkout steps and validation | src/features/checkout and src/lib/thorcommerce/storefront/queries/checkout.graphql |
| Customer authentication | src/lib/auth.ts, src/features/account, and src/app/api/auth/[...all] |
| Country, store, or currency behavior | src/lib/thorcommerce/config.ts, src/lib/request-context.ts, and src/proxy.ts |
| Storefront API transport | src/lib/thorcommerce/storefront/index.ts and endpoint.ts |
| Shared visual components | src/components |
Important repository conventions:
- Treat
.graphqldocuments as the source of truth for Storefront API selections. - Keep API keys and customer session tokens on the server.
- Reuse the request's store and currency context through the complete cart lifecycle.
- Re-read the returned cart after mutations because prices, discounts, stock, shipping eligibility, and totals can change together.
- Keep cart IDs in cookies and resource IDs and cursors opaque.
- Read
AGENTS.mdbefore using an AI coding agent; it points to the repository's Thor Commerce API skills.
src/
app/
[countryCode]/
(main)/ Storefront and customer account routes
(checkout)/ Checkout and order routes
api/auth/[...all]/ Better Auth route handler
components/ Shared UI primitives and commerce components
features/
account/ Login, registration, and account actions
cart/ Cart drawer, context, actions, and line items
checkout/ Customer, delivery, payment, and order flows
categories/ Category page UI
collections/ Collection page UI
home/ Home page UI
navbar/ Navigation and customer controls
products/ Product listing and product detail UI
lib/
auth.ts Better Auth configuration
request-context.ts Store and currency request context
thorcommerce/
config.ts Country, currency, and store configuration
storefront/ GraphQL documents, generated types, and API client
utils/ Money, price, map, and responsive utilities
proxy.ts Market routing and request header injection
| Command | Description |
|---|---|
pnpm dev |
Start the Next.js development server |
pnpm build |
Create a production build |
pnpm start |
Serve the production build |
pnpm test |
Run the regression tests |
pnpm typecheck |
Check TypeScript without building |
pnpm lint |
Run ESLint |
pnpm lint:fix |
Apply safe ESLint fixes |
pnpm codegen |
Generate TypeScript types and typed GraphQL documents |
Run the checks before publishing changes:
pnpm codegen
pnpm lint
pnpm test
pnpm buildThe tests cover product filtering and variant selection. A production build also checks TypeScript and route compilation. Authentication email delivery, payment completion, and shipping rules need integration testing against your own Thor project and payment gateway sandbox.
Deploy using a Next.js-compatible platform or run pnpm build followed by pnpm start on a Node.js server. Configure the environment variables on that server. No Cloudflare Worker adapter or deployment scripts are included. The optional CF-IPCountry hint is used only when the URL and saved market do not select a market.
Thor Commerce is a unified commerce platform for B2B, DTC, and hybrid businesses. Its GraphQL APIs connect catalog, pricing, inventory, customers, carts, checkout, and orders while leaving the storefront experience under your control.
Yes. The repository provides a decoupled Next.js frontend backed by the Thor Commerce Storefront GraphQL API. You can replace the design system, add routes, and extend GraphQL selections without coupling the UI to a monolithic commerce frontend.
Yes. The included checkout covers customer details, delivery, gateway selection, Stripe payments, manual payments, and order completion. Thor can also return a hosted checkout URL when that is a better fit for your implementation.
Yes. The application uses standard Next.js patterns. Use any Next.js-compatible platform and configure the environment variables listed above.
This is a working reference implementation and a strong starting point. Before launch, review your market configuration, authentication settings, payment methods, tax behavior, shipping rules, observability, accessibility, and deployment security for your business requirements.
Issues, ideas, and pull requests are welcome. If you find a bug or want to propose a storefront feature, open an issue with a clear reproduction or use case.
If this storefront saves you time, star the repository to help other Next.js and headless commerce developers discover Thor Commerce.