Solace Medusa Starter Audit

Repo: https://github.com/rigby-sh/solace-medusa-starter

Codebase Stats

MetricValue
Total files (TS/TSX/JS/JSX)348
Lines of code~21,500
Source locationsrc/ (Next.js App Router)
FrameworkNext.js 16.1.1, React 18.3.1
StylingTailwind CSS 3.4 + custom CSS variable preset + Medusa UI preset
State managementZustand (cart store)
Form handlingFormik + Yup
UI primitivesRadix UI, Headless UI
CarouselEmbla Carousel (with autoplay)
Notable deps@paypal/react-paypal-js, @stripe/react-stripe-js, next-themes, next-mdx-remote, sonner

Project Structure

Single Next.js storefront application (not a monorepo). Connects to external Medusa v2 backend and external Strapi CMS.

Key directories:

  • src/app/ — Next.js App Router pages and API routes
  • src/modules/ — 17 feature modules (account, blog, cart, categories, checkout, collections, common, content, home, layout, mdx, order, products, reset-password, search, skeletons, store)
  • src/lib/ — Data fetching, hooks, utilities, config
  • preset/ — Custom Tailwind preset (design tokens, dark/light mode)
  • e2e/ — Playwright end-to-end tests

Page Routes

RouteDescription
/[countryCode]/Homepage — hero, collections grid, bestsellers carousel, blog section (CMS-driven)
/[countryCode]/shopBrowse all products with filters, sorting, pagination
/[countryCode]/products/[handle]PDP — image gallery, variant picker, add to cart, tabs, related products
/[countryCode]/categories/[...category]Category listing (nested categories via catch-all)
/[countryCode]/collections/[handle]Collection listing
/[countryCode]/results/[query]Search results page
/[countryCode]/cartFull cart page
/[countryCode]/checkoutCheckout (separate layout)
/[countryCode]/order/confirmed/[id]Order confirmation
/[countryCode]/accountAccount hub (parallel routes: @login / @dashboard)
/[countryCode]/account/@dashboard/Account dashboard
/[countryCode]/account/@dashboard/ordersOrder history
/[countryCode]/account/@dashboard/orders/details/[id]Order detail
/[countryCode]/account/@dashboard/addressesSaved addresses
/[countryCode]/account/@dashboard/profileProfile settings
/[countryCode]/blogBlog listing with category/sort/search
/[countryCode]/blog/[slug]Blog post (MDX-rendered)
/[countryCode]/about-usAbout Us (CMS-driven)
/[countryCode]/faqFAQ page (CMS accordion)
/[countryCode]/privacy-policyPrivacy Policy
/[countryCode]/terms-and-conditionsTerms & Conditions
/[countryCode]/reset-passwordPassword reset
/api/strapi-revalidateWebhook for Strapi cache revalidation

Commerce Components

Product

ComponentPathLines
Product tile (card)src/modules/products/components/product-tile/index.tsx95
Product carouselsrc/modules/products/components/product-carousel/index.tsx77
Carousel wrapper (Embla)src/modules/products/components/product-carousel/carousel-wrapper.tsx91
Product actions (ATC, variant, qty)src/modules/products/components/product-actions/index.tsx220
Option select (color swatches)src/modules/products/components/product-actions/option-select.tsx88
Product tabs (accordion)src/modules/products/components/product-tabs/index.tsx168
Image gallery (grid + lightbox)src/modules/products/components/image-gallery/index.tsx78
Gallery dialog (lightbox + thumbnails)src/modules/products/components/image-gallery/gallery-dialog.tsx125
Image carousel (mobile swipe)src/modules/products/components/image-gallery/image-carousel.tsx79
Breadcrumbssrc/modules/products/templates/breadcrumbs.tsx

Cart

ComponentPathLines
Cart page templatesrc/modules/cart/templates/index.tsx33
Cart line itemsrc/modules/cart/components/item/index.tsx
Cart dropdown (header popover)src/modules/layout/components/cart-dropdown/index.tsx234
Sign-in promptsrc/modules/cart/components/sign-in-prompt/index.tsx

Checkout

ComponentPathLines
Checkout form (orchestrator)src/modules/checkout/templates/checkout-form/index.tsx35
Addresses stepsrc/modules/checkout/components/addresses/index.tsx276
Shipping addresssrc/modules/checkout/components/shipping-address/index.tsx260
Shipping stepsrc/modules/checkout/components/shipping/index.tsx183
Payment stepsrc/modules/checkout/components/payment/index.tsx297
Payment button (Stripe/PayPal/Manual)src/modules/checkout/components/payment-button/index.tsx332
Discount codesrc/modules/checkout/components/discount-code/index.tsx238

Faceted Filtering

ComponentPathLines
Product filters (collection, type, price)src/modules/store/components/filters/index.tsx132
Filter wrapper (collapsible)src/modules/store/components/filters/filter-wrapper/index.tsx41
Filter item (checkbox)src/modules/store/components/filters/filter-wrapper/filter-item.tsx
Active filters (pills)src/modules/store/components/filters/active-filters/index.tsx
Filters drawer (mobile)src/modules/store/components/filters/filters-drawer.tsx94
ComponentPathLines
Search boxsrc/modules/search/components/search-box/index.tsx93
Search dropdown (recent + recommended)src/modules/search/components/search-dropdown/index.tsx98
Search dialog (mobile fullscreen)src/modules/search/components/search-dialog/index.tsx127
Recent searchessrc/modules/search/components/search-dropdown/recent-searches.tsx
Search results templatesrc/modules/search/templates/search-results-template/index.tsx

Account

ComponentPathLines
Login formsrc/modules/account/components/login/index.tsx131
Register formsrc/modules/account/components/register/index.tsx262
Forgot passwordsrc/modules/account/components/forgot-password/index.tsx109
Order overviewsrc/modules/account/components/order-overview/index.tsx67
Profile detailssrc/modules/account/components/profile-details/index.tsx57
Profile password changesrc/modules/account/components/profile-password/index.tsx70
Address booksrc/modules/account/components/address-book/index.tsx118
Account navsrc/modules/account/components/account-nav/index.tsx
ComponentPathLines
Nav (mega menu)src/modules/layout/templates/nav/Multiple files
Footersrc/modules/layout/templates/footer/index.tsx171
Side menu (mobile)src/modules/layout/components/side-menu/index.tsx
Theme switchersrc/modules/layout/components/profile-dropdown/theme-switcher.tsx
Country selectsrc/modules/layout/components/country-select/index.tsx

CMS Content

ComponentPath
Bannersrc/modules/content/components/banner/index.tsx
Basic content sectionsrc/modules/content/components/basic-content-section/index.tsx
FAQ accordionsrc/modules/content/components/faq-accordion/index.tsx
Numerical sectionsrc/modules/content/components/numerical-section/index.tsx

Shared UI

30+ primitive components in src/modules/common/components/ (accordion, badge, box, button, checkbox, dialog, input, label, modal, radio, select, stepper, tabs, text, toast, etc.) plus 58 custom SVG icons.

Feature Inventory

Faceted Filtering

Three filter types:

  1. Collection — multi-select checkboxes (hidden on collection pages)
  2. Product type — multi-select checkboxes
  3. Price — predefined ranges: Under 100-501-1001+
  4. Material — commented out (// TO DO: Add material filter when backend is ready)

URL-param-driven, active filter pills, mobile drawer. Sort: Relevance, New in (price sort commented out).

Search

Custom search hitting Medusa backend /store/search endpoint. (algoliasearch dependency installed but never used.)

  • Text input with submit-on-enter
  • Stores last 5 searches in localStorage
  • Desktop: dropdown with recent searches + recommended products
  • Mobile: full-screen search dialog
  • No autocomplete/typeahead — submit-based navigation to /results/[query]
  • Results page uses same store template with filters and pagination

Checkout

Multi-step, single-page (3 steps):

  1. Addresses — shipping + optional separate billing
  2. Shipping — method selection
  3. Payment — Stripe (card + BLIK, Przelewy24, iDEAL, Bancontact), PayPal, Manual

Stepper indicator with numbered steps. Discount/promo codes supported.

No express checkout (no Apple Pay, Google Pay).

Grid + carousel + lightbox dialog:

  • Desktop: 2-column grid, first image full-width, “See more” button
  • Mobile: horizontal Embla carousel with swipe
  • Lightbox: full-screen dialog with thumbnail strip (horizontal mobile, vertical desktop)
  • No zoom

Customer Accounts

Complete:

  • Login (email/password)
  • Registration (name, email, phone, password with strength validation)
  • Forgot password (email-based reset)
  • Reset password (dedicated page)
  • Dashboard with recent orders
  • Order history with detail view
  • Saved addresses (CRUD, modal form)
  • Profile editing (name, email, phone, password)

SEO

  • OG tags: Per-page generateMetadata on PDP, blog, collections, categories
  • JSON-LD: None
  • Sitemap: next-sitemap.js configured (excludes /checkout, /account/*)
  • Static generation: generateStaticParams for products, collections, categories

Theming / Branding

  • CSS custom properties in preset/plugins/colors.js for light and dark mode
  • Full dark mode via next-themes with class strategy
  • Custom Tailwind preset layered on @medusajs/ui-preset
  • Semantic token classes (--bg-primary, --content-action-primary, etc.)
  • Reskin difficulty: Moderate-easy. Change ~60 CSS variable values in one file. No hardcoded colors in components.

Notable Features

Strapi CMS Integration

Deep integration:

  • Homepage hero, mid-banner, collections imagery — all CMS-managed
  • About Us, FAQ, Privacy Policy, Terms & Conditions pages
  • Full blog system with categories, sorting, search, MDX rendering
  • Product variant color/swatch management via Strapi
  • Webhook-based cache revalidation (/api/strapi-revalidate)

Other

  • Dark mode with theme toggle
  • E2E tests (Playwright)
  • “New product” badge (auto-detected, 7-day window)
  • Toast notifications (Sonner)
  • Inventory-aware quantity selector
  • Multi-region / i18n routing with country flags
  • Edge runtime on store template
  • Mega menu navigation with dropdown panels