Forking the Starter
The recommended approach is to fork the repository so you can customize freely while pulling upstream updates.1. Fork on GitHub
Go to github.com/spree/storefront and click Fork.2. Clone Your Fork
3. Add Upstream Remote
4. Pull Upstream Updates
When the official starter gets updates, pull them into your fork:Styling
The storefront uses Tailwind CSS 4, which replaces the traditionaltailwind.config.ts with CSS-native configuration via the @theme directive in src/app/globals.css.
Theme Customization
Edit the@theme inline block in src/app/globals.css to change colors, fonts, and other design tokens:
@theme inline become Tailwind utilities automatically — for example, --color-primary-500 maps to bg-primary-500, text-primary-500, etc.
Components
All components live insrc/components/ and can be customized or replaced:
Data Layer
To customize API behavior, modify the server actions insrc/lib/data/. Each file handles a specific domain:
| File | Purpose |
|---|---|
products.ts | Product listing and detail queries |
cart.ts | Cart operations (add, update, remove) |
checkout.ts | Checkout flow (addresses, shipping, completion) |
customer.ts | Authentication and profile management |
addresses.ts | Address CRUD |
orders.ts | Order history |
payment.ts | Payment sessions and processing |
categories.ts | Categories |
countries.ts | Country and region data |
cookies.ts | Auth check helper |
store.ts | Store configuration |
credit-cards.ts | Saved payment methods |
gift-cards.ts | Gift card management |
utils.ts | Shared helpers (error handling, fallbacks) |
@spree/sdk directly, using helpers in src/lib/spree/ for auth cookies and locale resolution. You can add custom logic, caching strategies, or additional transformations as needed.
Adding New Pages
Follow the existing App Router pattern with localized routes. Place pages under the(storefront) route group to inherit the shared header/footer layout:
Transactional Emails
Customer-facing emails are rendered in the storefront using react-email and sent via Resend. The Spree backend delivers order/shipment/password events to the storefront via webhooks.Templates
Email templates are React components insrc/lib/emails/:
| File | Event | Description |
|---|---|---|
order-confirmation.tsx | order.completed | Items, totals, addresses, delivery method |
order-canceled.tsx | order.canceled | Cancellation notice with items |
shipment-shipped.tsx | order.shipped | Tracking number and link |
password-reset.tsx | customer.password_reset_requested | Reset button and fallback link |
@react-email/components for email-safe layout primitives.
Previewing
http://localhost:3000.
Webhook Handler
The webhook route (src/app/api/webhooks/spree/route.ts) uses createWebhookHandler from src/lib/spree/webhooks:
- Create a template in
src/lib/emails/ - Add a handler function in
src/lib/webhooks/handlers.ts - Register the event in
route.ts - Subscribe to the event in Spree Admin → Webhooks
Local Development
In dev, emails are written to.next/emails/ as HTML files — no Resend key needed. Use Cloudflare Tunnel to receive webhooks locally:
Building a Custom Storefront
If you prefer to build from scratch instead of forking the starter, you can use the@spree/sdk package directly in any Next.js application. The storefront’s src/lib/spree/ directory contains reusable helpers for cookie-based auth, locale resolution, middleware, and webhook verification that you can copy into your own project.
