Medusa

Medusa Storefront Template

Dotenv

MEDUSA_BACKEND_URL=https://backend.your_store.com
NEXT_PUBLIC_BASE_URL=http://localhost:8000
NEXT_PUBLIC_DEFAULT_REGION=us
NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_...
NEXT_PUBLIC_STRIPE_KEY=pk_test_...
CLOUDFRONT_URL=https://cdn.your_store.com

Next.js Configuration

const nextConfig = {
  //...
  images: {
    qualities: [50],
    remotePatterns: [
      {
        protocol: "http",
        hostname: "localhost",
      },
      { // Note: needed to serve images from /public folder
        protocol: process.env.NEXT_PUBLIC_BASE_URL?.startsWith('https') ? 'https' : 'http',
        hostname: process.env.NEXT_PUBLIC_BASE_URL?.replace(/^https?:\/\//, ''),
      },
      { // Note: only needed when using local-file for product media
        protocol: "https",
        hostname: process.env.MEDUSA_BACKEND_URL?.replace('https://', ''),
      },
      ...(process.env.CLOUDFRONT_URL ? [{ // Note: needed when using AWS S3 bucket storage for media
        protocol: process.env.CLOUDFRONT_URL?.startsWith('https') ? 'https' : 'http',
        hostname: process.env.CLOUDFRONT_URL?.replace(/^https?:\/\//, ''),
      }] : []),
      { // Allow direct AWS S3 bucket URLs
        protocol: 'https',
        hostname: '*.s3.*.amazonaws.com',
      },
      { // Legacy/global S3 endpoint
        protocol: 'https',
        hostname: 's3.amazonaws.com',
      },
    ],
  }
  //...
}

File Structure

  • src
    • app
      • api
        • revalidate
          • route.ts:
      • [countryCode]
        • (checkout)
          • checkout
            • page.tsx:
          • layout.tsx:
        • (main)
          • page.tsx: Modify store home page title and meta description
          • account
            • @dashboard
              • orders
                • page.tsx: Edit customer order history
            • @login
              • page.tsx:
          • categories
            • [...category]
              • page.tsx:
          • collections
            • [handle]
              • page.tsx:
          • policy
            • privacy
            • refund
            • return
          • products
            • [handle]
              • page.tsx: Edit title, meta description and openGraph.
          • store
            • page.tsx: Generic store main page, listing all products with pagination
        • (checkout)
          • layout.tsx:
    • i18n
      • en-US.json:
      • zh-CN.json:
    • lib
      • constants.tsx:
    • modules
      • account
        • components
          • order-overview
            • index.tsx:
      • checkout
        • components
          • shipping
            • index.tsx:
      • common
        • components
          • logo
            • index.tsx:
        • icons
          • alipay.tsx:
      • home
        • components
          • featured-products
          • hero
          • highlights
      • layout
        • components
          • side-menu
            • index.tsx:
          • top-nav.tsx:
        • templates
          • footer
            • index.tsx:
          • nav
            • index.tsx:
      • order
        • components
          • help
            • index.tsx: Edit the customer service information displayed on the checkout completion page.
        • templates
          • order-completed-template.tsx:
          • order-details-template.tsx: Order details page which user opened from order history page in account.
      • products
        • components
          • image-gallery
            • index.tsx:
          • related-products
            • index.tsx:
        • templates
          • index.tsx:
      • order
        • templates
          • order-completed-template.tsx: Order placement successful page
      • store
        • templates
          • paginated-products.tsx:
    • styles
      • global.css

Vercel Deployment

Vercel Analytics

  1. Edit src/app/layout.tsx:
import { getBaseURL } from "@lib/util/env"
import { Metadata } from "next"
import Script from "next/script"
import { Analytics } from "@vercel/analytics/next"
import "styles/globals.css"

export const metadata: Metadata = {
  metadataBase: new URL(getBaseURL()),
}

export default function RootLayout(props: { children: React.ReactNode }) {
  return (
    <html lang="en" data-mode="light">
      <body>
        <main className="relative">{props.children}</main>
        <Analytics />
      </body>
    </html>
  )
}
Previous
Digital Product
Next
Conda