Solace Medusa Starter Audit
Codebase Stats
| Metric | Value |
|---|---|
| Total files (TS/TSX/JS/JSX) | 348 |
| Lines of code | ~21,500 |
| Source location | src/ (Next.js App Router) |
| Framework | Next.js 16.1.1, React 18.3.1 |
| Styling | Tailwind CSS 3.4 + custom CSS variable preset + Medusa UI preset |
| State management | Zustand (cart store) |
| Form handling | Formik + Yup |
| UI primitives | Radix UI, Headless UI |
| Carousel | Embla 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 routessrc/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, configpreset/— Custom Tailwind preset (design tokens, dark/light mode)e2e/— Playwright end-to-end tests
Page Routes
| Route | Description |
|---|---|
/[countryCode]/ | Homepage — hero, collections grid, bestsellers carousel, blog section (CMS-driven) |
/[countryCode]/shop | Browse 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]/cart | Full cart page |
/[countryCode]/checkout | Checkout (separate layout) |
/[countryCode]/order/confirmed/[id] | Order confirmation |
/[countryCode]/account | Account hub (parallel routes: @login / @dashboard) |
/[countryCode]/account/@dashboard/ | Account dashboard |
/[countryCode]/account/@dashboard/orders | Order history |
/[countryCode]/account/@dashboard/orders/details/[id] | Order detail |
/[countryCode]/account/@dashboard/addresses | Saved addresses |
/[countryCode]/account/@dashboard/profile | Profile settings |
/[countryCode]/blog | Blog listing with category/sort/search |
/[countryCode]/blog/[slug] | Blog post (MDX-rendered) |
/[countryCode]/about-us | About Us (CMS-driven) |
/[countryCode]/faq | FAQ page (CMS accordion) |
/[countryCode]/privacy-policy | Privacy Policy |
/[countryCode]/terms-and-conditions | Terms & Conditions |
/[countryCode]/reset-password | Password reset |
/api/strapi-revalidate | Webhook for Strapi cache revalidation |
Commerce Components
Product
| Component | Path | Lines |
|---|---|---|
| Product tile (card) | src/modules/products/components/product-tile/index.tsx | 95 |
| Product carousel | src/modules/products/components/product-carousel/index.tsx | 77 |
| Carousel wrapper (Embla) | src/modules/products/components/product-carousel/carousel-wrapper.tsx | 91 |
| Product actions (ATC, variant, qty) | src/modules/products/components/product-actions/index.tsx | 220 |
| Option select (color swatches) | src/modules/products/components/product-actions/option-select.tsx | 88 |
| Product tabs (accordion) | src/modules/products/components/product-tabs/index.tsx | 168 |
| Image gallery (grid + lightbox) | src/modules/products/components/image-gallery/index.tsx | 78 |
| Gallery dialog (lightbox + thumbnails) | src/modules/products/components/image-gallery/gallery-dialog.tsx | 125 |
| Image carousel (mobile swipe) | src/modules/products/components/image-gallery/image-carousel.tsx | 79 |
| Breadcrumbs | src/modules/products/templates/breadcrumbs.tsx | — |
Cart
| Component | Path | Lines |
|---|---|---|
| Cart page template | src/modules/cart/templates/index.tsx | 33 |
| Cart line item | src/modules/cart/components/item/index.tsx | — |
| Cart dropdown (header popover) | src/modules/layout/components/cart-dropdown/index.tsx | 234 |
| Sign-in prompt | src/modules/cart/components/sign-in-prompt/index.tsx | — |
Checkout
| Component | Path | Lines |
|---|---|---|
| Checkout form (orchestrator) | src/modules/checkout/templates/checkout-form/index.tsx | 35 |
| Addresses step | src/modules/checkout/components/addresses/index.tsx | 276 |
| Shipping address | src/modules/checkout/components/shipping-address/index.tsx | 260 |
| Shipping step | src/modules/checkout/components/shipping/index.tsx | 183 |
| Payment step | src/modules/checkout/components/payment/index.tsx | 297 |
| Payment button (Stripe/PayPal/Manual) | src/modules/checkout/components/payment-button/index.tsx | 332 |
| Discount code | src/modules/checkout/components/discount-code/index.tsx | 238 |
Faceted Filtering
| Component | Path | Lines |
|---|---|---|
| Product filters (collection, type, price) | src/modules/store/components/filters/index.tsx | 132 |
| Filter wrapper (collapsible) | src/modules/store/components/filters/filter-wrapper/index.tsx | 41 |
| 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.tsx | 94 |
Search
| Component | Path | Lines |
|---|---|---|
| Search box | src/modules/search/components/search-box/index.tsx | 93 |
| Search dropdown (recent + recommended) | src/modules/search/components/search-dropdown/index.tsx | 98 |
| Search dialog (mobile fullscreen) | src/modules/search/components/search-dialog/index.tsx | 127 |
| Recent searches | src/modules/search/components/search-dropdown/recent-searches.tsx | — |
| Search results template | src/modules/search/templates/search-results-template/index.tsx | — |
Account
| Component | Path | Lines |
|---|---|---|
| Login form | src/modules/account/components/login/index.tsx | 131 |
| Register form | src/modules/account/components/register/index.tsx | 262 |
| Forgot password | src/modules/account/components/forgot-password/index.tsx | 109 |
| Order overview | src/modules/account/components/order-overview/index.tsx | 67 |
| Profile details | src/modules/account/components/profile-details/index.tsx | 57 |
| Profile password change | src/modules/account/components/profile-password/index.tsx | 70 |
| Address book | src/modules/account/components/address-book/index.tsx | 118 |
| Account nav | src/modules/account/components/account-nav/index.tsx | — |
Navigation / Layout
| Component | Path | Lines |
|---|---|---|
| Nav (mega menu) | src/modules/layout/templates/nav/ | Multiple files |
| Footer | src/modules/layout/templates/footer/index.tsx | 171 |
| Side menu (mobile) | src/modules/layout/components/side-menu/index.tsx | — |
| Theme switcher | src/modules/layout/components/profile-dropdown/theme-switcher.tsx | — |
| Country select | src/modules/layout/components/country-select/index.tsx | — |
CMS Content
| Component | Path |
|---|---|
| Banner | src/modules/content/components/banner/index.tsx |
| Basic content section | src/modules/content/components/basic-content-section/index.tsx |
| FAQ accordion | src/modules/content/components/faq-accordion/index.tsx |
| Numerical section | src/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:
- Collection — multi-select checkboxes (hidden on collection pages)
- Product type — multi-select checkboxes
- Price — predefined ranges: Under 100-501-1001+
- 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):
- Addresses — shipping + optional separate billing
- Shipping — method selection
- 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).
Image Gallery
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
generateMetadataon PDP, blog, collections, categories - JSON-LD: None
- Sitemap:
next-sitemap.jsconfigured (excludes/checkout,/account/*) - Static generation:
generateStaticParamsfor products, collections, categories
Theming / Branding
- CSS custom properties in
preset/plugins/colors.jsfor light and dark mode - Full dark mode via
next-themeswithclassstrategy - 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