A Technical Tutorial for Lead Developers and Technical Architects
Published by Askan Technologies | February 2026
The default MedusaJS starter storefront gets you running quickly, but production ecommerce demands more. Custom product pages, tailored checkout experiences, personalized navigation, and brand-specific design systems require a storefront built from the ground up with your business logic baked in.
Next.js 15 brings server components, streaming, and the App Router to a level of maturity that makes it the ideal frontend framework for headless commerce. Combined with MedusaJS's clean API layer, you get a storefront that loads in under a second, renders dynamically for SEO, and gives your development team complete creative control.
This walkthrough covers the complete architecture for building a production-grade MedusaJS storefront with Next.js 15. We cover project structure, API integration patterns, product pages, cart management, checkout flows, and deployment strategies. This is not a beginner tutorial. It assumes familiarity with React, TypeScript, and basic MedusaJS concepts.
Why Next.js 15 for MedusaJS Storefronts
Why Next.js 15 for MedusaJS Storefronts
Before writing code, it is worth understanding why Next.js 15 has become the dominant frontend choice for MedusaJS implementations. Other frameworks like Astro, Remix, and SvelteKit are viable alternatives, but Next.js 15 offers the strongest combination of features for commerce.
Framework Comparison for MedusaJS Storefronts
Framework Comparison for MedusaJS Storefronts
Feature | Next.js 15 | Astro | Remix | SvelteKit |
|---|---|---|---|---|
Server Components | Native | Partial | No | No |
Streaming SSR | Built-in | Limited | Built-in | Limited |
Image Optimization | Built-in | Plugin | Manual | Plugin |
ISR Support | Native | No | No | No |
Commerce Ecosystem | Extensive | Growing | Moderate | Small |
Enterprise Adoption | Very High | Moderate | Growing | Low |
Learning Curve | Moderate | Low | Moderate | Low |
Next.js 15's React Server Components architecture is particularly powerful for ecommerce. Product pages, category listings, and content pages render entirely on the server, sending minimal JavaScript to the browser. Cart interactions, search, and checkout use client components where interactivity is needed. This hybrid approach delivers fast initial loads alongside rich interactivity.
Project Architecture: Thinking in Layers
Project Architecture: Thinking in Layers
A well-structured MedusaJS + Next.js 15 storefront separates concerns into distinct layers. This architecture scales from a simple catalog to a complex multi-region commerce platform without major refactoring.
Layer 1: MedusaJS API Client
Layer 1: MedusaJS API Client
Create a centralized API client that handles all communication with your MedusaJS backend. This layer manages authentication tokens, request formatting, error handling, and response typing.
// lib/medusa-client.ts
// Centralized client with typed responses
// Handles: Products, Cart, Checkout, Customer, Region APIs
// Uses: fetch() with proper headers and error boundaries The API client should be a singleton that all server components import. Never make MedusaJS API calls directly from components. This ensures consistent error handling and caching strategies, and makes it simple to swap backends if needed.
Layer 2: Data Fetching with Server Components
Layer 2: Data Fetching with Server Components
Next.js 15 Server Components fetch data during rendering without client-side JavaScript. For product pages, the browser receives fully rendered HTML with zero loading spinners.
// app/products/[handle]/page.tsx
// Server Component: fetches product data at request time
// Uses: medusa-client.getProduct(handle)
// Returns: Fully rendered product page with SEO metadata Server components handle product listings, category pages, CMS content, and any read-only data. They never import useState, useEffect, or any browser-only APIs.
Layer 3: Client Components for Interactivity
Layer 3: Client Components for Interactivity
Cart operations, quantity selectors, variant pickers, search autocomplete, and checkout forms require client-side interactivity. These components use the 'use client' directive and communicate with MedusaJS through API routes.
// components/cart/AddToCartButton.tsx
// 'use client' directive for cart state and API calls
// Uses: React state, cart context, optimistic updates The key principle: keep client components as small as possible. A product page might be 95% server-rendered HTML with a small client component for the Add to Cart button and variant selector.
Layer 4: API Routes for Sensitive Operations
Layer 4: API Routes for Sensitive Operations
Checkout processing, payment intent creation, and customer authentication should flow through Next.js API routes rather than direct client-to-MedusaJS calls. This keeps your MedusaJS API keys server-side and allows you to add business logic between the frontend and backend.
Building Product Pages That Convert
Building Product Pages That Convert
Product pages are the revenue engine of your storefront. The architecture decisions here directly impact page speed, SEO rankings, and conversion rates.
Dynamic Metadata for SEO
Dynamic Metadata for SEO
Next.js 15's generateMetadata function creates dynamic meta tags based on MedusaJS product data. Each product page gets a unique title, description, Open Graph image, and structured data without any client-side JavaScript.
This approach ensures every product page is fully optimized for search engines from the first render. No JavaScript execution is required for crawlers to index your complete catalog.
Image Optimization Strategy
Image Optimization Strategy
Product images are typically the heaviest assets on ecommerce pages. Next.js 15's Image component combined with MedusaJS's media handling creates an optimized pipeline:
Automatic WebP/AVIF conversion: Next.js converts images to modern formats based on browser support
Responsive sizing: Generate srcset attributes that serve appropriately sized images for every viewport
Lazy loading: Below-the-fold images load only when they approach the viewport
Priority hints: The hero product image gets priority loading to improve Largest Contentful Paint
Variant Selection and Real-Time Pricing
Variant Selection and Real-Time Pricing
Product variant selection (size, color, material) is one of the few areas requiring client-side interactivity on product pages. The implementation should update pricing, inventory status, and product images instantly without full page reloads.
Use React state for the selected variant, and pre-fetch all variant data in the server component. Variant switching becomes instantaneous because no additional API calls are needed.
Cart Management Architecture
Cart Management Architecture
Cart state in a headless commerce setup requires careful design. MedusaJS manages the cart server-side, but your frontend needs to reflect cart state instantly for a smooth user experience.
Optimistic Updates Pattern
Optimistic Updates Pattern
When a customer clicks Add to Cart, the UI should update immediately. Do not wait for the MedusaJS API response. Implement optimistic updates that assume success and roll back on error:
User clicks Add to Cart
UI immediately shows updated cart count and item
API call fires in the background to MedusaJS
On success: cart state syncs with server response
On error: roll back UI and show error message
This pattern makes your storefront feel instant, even on slow networks. It is the difference between a 50ms perceived response and a 500ms API wait.
Custom Checkout Flow Design
Custom Checkout Flow Design
The checkout flow is where MedusaJS's flexibility truly shines. You have complete control over every step, every field, and every validation rule.
Multi-Step vs Single-Page Checkout
Multi-Step vs Single-Page Checkout
Aspect | Multi-Step Checkout | Single-Page Checkout |
|---|---|---|
Best For | Complex orders, B2B | Simple B2C, fast purchase |
Conversion Rate | Generally lower | Generally higher |
Mobile Experience | Better (smaller forms) | Can feel crowded |
Implementation | More complex routing | Simpler architecture |
Analytics | Step-level funnel tracking | Field-level tracking |
For most B2C stores, we recommend a hybrid approach: a single page with collapsible sections that expand as the customer progresses. This delivers visual simplicity with focused, step-like progression.
Payment Integration: Stripe with MedusaJS
Payment Integration: Stripe with MedusaJS
Stripe is the most common payment provider for MedusaJS stores. The integration follows a specific flow:
Create Payment Session: When customer reaches checkout, create a MedusaJS payment session linked to Stripe
Collect Payment Details: Use Stripe Elements client-side to securely collect card information
Confirm Payment: Submit payment through MedusaJS, which coordinates with Stripe
Handle Webhooks: Set up Stripe webhooks for payment confirmations, disputes, and refunds
For complex payment setups, explore our Integration Services
Deployment and Performance Optimization
Deployment and Performance Optimization
Recommended Architecture
Recommended Architecture
MedusaJS Backend: AWS ECS, Railway, or DigitalOcean with managed PostgreSQL and Redis
Next.js Frontend: Vercel for optimal edge caching, image optimization, and preview deployments
CDN Layer: Cloudflare for DDoS protection, caching, and global DNS
Media Storage: AWS S3 or Cloudflare R2 for product images with CDN
Performance Targets
Performance Targets
Metric | Target |
|---|---|
Largest Contentful Paint | < 1.5 seconds |
First Input Delay | < 100ms |
Cumulative Layout Shift | < 0.1 |
Time to First Byte | < 200ms |
Total Page Weight | < 500KB initial load |
Lighthouse Score | > 90 |
Common Pitfalls and How to Avoid Them
Common Pitfalls and How to Avoid Them
Over-fetching product data: Only request the fields you need from MedusaJS APIs
Client component creep: Resist adding 'use client' to everything. Each adds JavaScript to the bundle
Missing error boundaries: API failures should not crash entire pages. Use meaningful fallbacks
Ignoring mobile checkout: 70%+ of ecommerce traffic is mobile. Design for thumbs first
Skipping structured data: Product schema markup (JSON-LD) significantly impacts search appearance
Hard-coding region logic: Use MedusaJS region API for currency, tax, and shipping
Need Expert Help Building Your MedusaJS Storefront?
Need Expert Help Building Your MedusaJS Storefront?
Building a production-grade headless storefront requires expertise in both MedusaJS backend architecture and modern frontend engineering. At Askan Technologies, our team specializes in custom MedusaJS implementations delivering sub-second page loads, optimized checkout flows, and seamless integrations.
Our services cover the full lifecycle: Theme Development for custom Next.js storefronts, UI/UX Services for conversion-optimized design, Extension Development for custom backend modules, and Integration Services for payment, shipping, and ERP connections.
Visit ecom.askantech.com or schedule a technical consultation to discuss your storefront requirements.
