Skip to main content
A fully functional online store for handmade jewelry with a browsable product catalog, persistent shopping cart, Stripe-powered checkout, order management, and automated customer notifications. Customers can browse collections, filter by category, add items to their cart, pay securely, and receive order confirmation emails with tracking details.By the end of this recipe you will have a production-ready store that you can customize, rebrand, and launch as your own product.

Tech stack

You do not need to understand these technologies. Rocket handles them automatically. This table is for reference.
TechnologyRole
Next.js + TypeScriptFrontend framework and server-side rendering
SupabaseDatabase (products, orders, users), authentication, and file storage for product images
StripeCheckout sessions and payment processing
SendGrid or ResendOrder confirmation and shipping notification emails
Google AnalyticsConversion tracking and traffic attribution
NetlifyProduction deployment and custom domain

Architecture overview

The store follows a straightforward data flow:
  1. Browse: Customers explore products pulled from Supabase, with images served from Supabase Storage.
  2. Cart: Selected items are stored in a client-side cart that syncs to Supabase for logged-in users.
  3. Checkout: The cart is sent to Stripe Checkout for secure payment processing.
  4. Order saved: On successful payment, a Stripe webhook writes the order to Supabase and updates inventory.
  5. Notification: An order confirmation email is sent through SendGrid or Resend with order details and estimated delivery.
  6. Analytics: GA4 tracks product views, add-to-cart events, and completed purchases for conversion analysis.

How long does it take?

PhaseWhat you are buildingEstimated time
SetupProject, Supabase, catalog5-10 minutes
StorefrontProducts, cart, checkout10-15 minutes
PaymentsStripe integration5 minutes
Post-purchaseEmails, order history5-10 minutes
LaunchAnalytics, deploy5 minutes
TotalComplete store30-45 minutes

Step-by-step build

1

Start your project

Open Rocket and describe the full scope of your store so it can scaffold the right structure from the beginning.
Build an e-commerce store for a handmade jewelry brand called "Luna & Stone." The store should have a homepage with featured products, a product catalog page with category filters (rings, necklaces, bracelets, earrings), individual product detail pages, a shopping cart, Stripe checkout, and an order confirmation page. Use Next.js with TypeScript and a clean, modern design with a warm neutral color palette.
Rocket generates the full project structure, page layouts, navigation, and placeholder product data.
2

Connect Supabase and set up the product catalog

Connect your Supabase project and ask Rocket to create the database schema for your store.
Connect Supabase. Create these tables:
- products: id, name, description, price (integer, in cents), category (enum: rings, necklaces, bracelets, earrings), images (text array of storage URLs), inventory_count, is_featured, created_at
- customers: id (linked to Supabase Auth user), email, name, shipping_address (jsonb), created_at
- orders: id, customer_id (FK to customers), stripe_session_id, status (enum: pending, paid, shipped, delivered), total_amount, shipping_address (jsonb), created_at
- order_items: id, order_id (FK to orders), product_id (FK to products), quantity, unit_price
Enable row-level security so customers can only read products and view their own orders. Add a Supabase Storage bucket called "product-images" with public read access.
Seed your products table with 8-12 sample items so you have real data to work with while building. You can ask Rocket to generate sample jewelry data with realistic names, descriptions, and prices.
3

Build product listing and detail pages

Replace the placeholder data with live Supabase queries and build out the shopping experience.
Update the product catalog page to fetch products from Supabase. Add:
- A grid layout showing product image, name, and price
- Category filter buttons that update the query without a full page reload
- A "Featured" section on the homepage showing products where is_featured is true
- Individual product pages at /products/[id] with an image gallery, full description, price, and an "Add to Cart" button
- Loading skeletons while products are being fetched
Use Supabase Storage URLs for product images.
4

Implement the shopping cart

Add a persistent cart that works for both guests and logged-in users.
Add a shopping cart with the following behavior:
- Cart icon in the header showing item count
- Slide-out cart drawer that shows items, quantities, and subtotal
- Plus/minus buttons to update quantity, with a max of the product's inventory_count
- Remove item button
- Store the cart in localStorage for guest users
- When a user logs in, merge the localStorage cart with any existing cart in Supabase
- Cart page at /cart with a full summary and a "Proceed to Checkout" button
Test the cart with multiple products and edge cases: adding the same item twice, removing the last item, and refreshing the page to verify persistence.
5

Connect Stripe for checkout

Wire up Stripe Checkout so customers can pay securely.
Connect Stripe and implement checkout:
- When the user clicks "Proceed to Checkout," create a Stripe Checkout session with line items from the cart (product name, unit price, quantity, and product image)
- Include a success URL (/order-confirmation?session_id={CHECKOUT_SESSION_ID}) and a cancel URL (/cart)
- Add a Stripe webhook handler for checkout.session.completed that:
1. Creates an order in the orders table with status "paid"
2. Creates order_items for each product
3. Decrements inventory_count for each purchased product
- On the success page, fetch order details using the session_id and show a confirmation with order number, items purchased, and total
Make sure your Stripe webhook secret is stored as an environment variable, not hardcoded. Rocket handles this automatically when you connect Stripe through the integrations panel.
6

Add order management and history

Give customers visibility into their past orders and current order status.
Add an order history page at /account/orders that:
- Requires authentication (redirect to login if not signed in)
- Shows a list of all orders for the logged-in customer, sorted by date
- Each order card shows: order number, date, status badge (paid, shipped, delivered), item count, and total amount
- Clicking an order opens a detail view with individual items, quantities, prices, and shipping address
- Add a Supabase real-time subscription so the status badge updates live when an order status changes
7

Set up email notifications

Send customers an email when their order is confirmed.
Connect Resend (or SendGrid). When the Stripe webhook confirms a successful payment, send an order confirmation email to the customer that includes:
- Order number and date
- List of items with name, quantity, and price
- Order total and shipping address
- A "View Order" button linking to /account/orders/[id]
- Brand header with the Luna & Stone logo
Use a clean, responsive HTML email template that looks good on mobile.
If you want to add shipping notification emails later, you can ask Rocket to send another email when the order status changes to “shipped.”
8

Add analytics tracking

Track the full purchase funnel so you can see where customers drop off.
Connect Google Analytics (GA4) and add e-commerce event tracking:
- view_item: when a customer opens a product detail page
- add_to_cart: when a customer adds a product to the cart
- begin_checkout: when the customer clicks "Proceed to Checkout"
- purchase: on the order confirmation page, with transaction_id, value, and items
Include UTM parameter tracking so I can measure which marketing channels drive sales.
9

Polish and deploy

Add final touches and ship your store.
Before deploying, make these improvements:
- Add SEO metadata (title, description, Open Graph image) to the homepage, catalog page, and each product page
- Add a favicon and branded loading state
- Make sure all pages are fully responsive on mobile
- Add an empty cart state with a "Continue Shopping" link
- Add a 404 page for products that do not exist
Use the Launch button in your Rocket project to deploy to the web. Rocket handles the Netlify build configuration automatically. Make sure all required environment variables are set in your project’s integration settings before launching.
After deploying, connect a custom domain through Netlify and set up an SSL certificate. You can do this from the Netlify dashboard or ask Rocket to guide you through it.

Customization ideas

Track stock levels and show “Out of Stock” badges when inventory runs out. Ask Rocket to add an admin page where you can update inventory counts and receive low-stock alerts.
Add inventory management. Show "Out of Stock" on product cards when inventory_count is 0 and disable the Add to Cart button. Create an admin page at /admin/inventory that lists all products with current stock levels and lets me update quantities. Send me an email when any product drops below 5 units.
Let customers apply promo codes at checkout for percentage or fixed-amount discounts.
Add a discount codes system. Create a discount_codes table in Supabase with fields for code, type (percentage or fixed), value, max_uses, current_uses, and expiry_date. Add a "Promo Code" input on the cart page that validates the code and shows the discounted total. Pass the discount to Stripe as a coupon on the checkout session.
Let customers leave ratings and reviews on products they have purchased.
Add product reviews. Create a reviews table with product_id, customer_id, rating (1-5), comment, and created_at. On the product detail page, show the average rating, total review count, and a list of reviews. Only allow customers who have purchased the product to leave a review. Add a star rating input component.
Let logged-in customers save products to a wishlist for later.
Add a wishlist feature. Create a wishlists table with customer_id and product_id. Add a heart icon on each product card that toggles the item in the wishlist. Create a /account/wishlist page showing all saved items with an "Add to Cart" button on each one. Require authentication to use the wishlist.
Build a back-office dashboard for managing products, orders, and customers.
Add an admin panel at /admin with role-based access (add an is_admin boolean to the customers table). Include:
- Dashboard with today's revenue, total orders, and top-selling products
- Product management: add, edit, delete products and upload images
- Order management: view all orders, update status (paid > shipped > delivered), and search by order number or customer email
- Customer list with order history per customer

Troubleshooting

If items disappear from the cart after refreshing, the cart may not be saving to the browser’s storage. Ask Rocket to fix it:
The shopping cart loses all items when I refresh the page. Make sure the cart state is saved to localStorage on every update and loaded back when the page mounts, so items persist across page refreshes and navigation.
If a customer pays but no order shows up in the app, the Stripe webhook may not be configured correctly. Make sure Stripe is connected in your project’s Integrations panel, then ask Rocket to debug:
Customers are completing Stripe checkout but orders are not being created in Supabase. Debug the Stripe webhook handler for checkout.session.completed. Make sure it creates the order, saves order items, and decrements inventory. Add error logging so I can see what is failing.
If product images appear broken, the Supabase Storage bucket may not have public access enabled. Ask Rocket to check:
Product images are showing as broken on the store. Review the image URL format in the code and make sure it matches the Supabase Storage URL pattern. Fix any mismatches. Remind me to verify that the storage bucket has public read access in the Supabase dashboard.
If the amount charged in Stripe is different from what the cart shows, the prices may be calculated on the wrong side. Ask Rocket to fix it:
The Stripe checkout amount does not match the cart total. Make sure product prices are fetched from Supabase on the server side when creating the Stripe Checkout session, instead of using the prices from the client-side cart.