JS

Medusa

What is Medusa?

Medusa is an ecommerce platform with a built-in framework for customization that allows you to build custom commerce applications without reinventing core commerce logic.


Installation

Reference URL

Run the following command and replace <NAME> and <DATABASE_URL> with your store name:

$ npx create-medusa-app@latest <NAME> --with-nextjs-starter --db-url "<DATABASE_URL>" --no-migrations

Medusa CLI

$ npx medusa user -e admin@medusajs.com -p supersecret

Deployment

Railway

  1. Click on Create on right top corner
  2. Choose GitHub Repo
  3. Select or authorize the Medusa Backend repository from your own GitHub account
  4. Open the Variables tab by clicking on the newly created service
  5. Deploy the new service
NODE_ENV="production"
PORT="9000"
ADMIN_CORS=https://${{RAILWAY_PUBLIC_DOMAIN}},https://${{RAILWAY_PRIVATE_DOMAIN}}
AUTH_CORS=https://${{RAILWAY_PUBLIC_DOMAIN}},https://${{RAILWAY_PRIVATE_DOMAIN}}
STORE_CORS=${{Storefront.NEXT_PUBLIC_BASE_URL}}
COOKIE_SECRET=supersecret
JWT_SECRET=supersecret
DATABASE_URL=${{Postgres.DATABASE_URL}}
REDIS_URL=${{Redis.REDIS_URL}}?family=0
S3_ACCESS_KEY_ID=<IAM_USER_ACCESS_KEY_ID>
S3_SECRET_ACCESS_KEY=<IAM_USER_SECRET_ACCESS_KEY>
S3_BUCKET=<bucket_name>
S3_ENDPOINT=https://s3.<region>.amazonaws.com
S3_FILE_URL=https://<bucket_name>.s3.<region>.amazonaws.com
S3_REGION=<region>

Storefront

  1. Click on Create on right top corner
  2. Choose GitHub Repo
  3. Select or authorize the Medusa Storefront repository from your own GitHub account
  4. Open the Variables tab by clicking on the newly created service
  5. Deploy the new service
PORT=8000
MEDUSA_BACKEND_URL=https://${{Backend.RAILWAY_PUBLIC_DOMAIN}}
NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_*****************
NEXT_PUBLIC_BASE_URL=https://${{RAILWAY_PUBLIC_DOMAIN}}
NEXT_PUBLIC_DEFAULT_REGION=us
NEXT_PUBLIC_STRIPE_KEY=
REVALIDATE_SECRET=supersecret
S3_FILE_URL=<bucket_name>.s3.<region>.amazonaws.com
  1. Open the Settings tab by clicking on the newly created service
  2. Click on **Custom Domain ** under Public Networking, select the port in the dropdown menu or type 8000 which was defined in the Variables.

Modules

Redis

Reference URL

import { Modules } from "@medusajs/framework/utils"

// ...

module.exports = defineConfig({
    // ...
    modules: [
        {
            resolve: "@medusajs/medusa/cache-redis",
            options: {
                redisUrl: process.env.CACHE_REDIS_URL,
            },
        },
    ],
})

AWS S3 Storage

Reference URL

  • Create AWS user with AmazonS3FullAccess permissions.
  • Create AWS IAM user access key ID and secret access key.
  • Create S3 bucket with the "Public Access setting" enabled:
  1. On your bucket's dashboard, click on the Permissions tab.
  2. Click on the Edit button of the Block public access (bucket settings) section.
  3. In the form that opens, don't toggle any checkboxes and click the "Save changes" button.
  4. Confirm saving the changes by entering confirm in the pop-up that shows.
  5. Back on the Permissions page, scroll to the Object Ownership section and click the Edit button.
  6. In the form that opens:
    • Choose the "ACLs enabled" card.
    • Click on the "Save changes" button.
  7. Back on the Permissions page, scroll to the "Access Control List (ACL)" section and click on the Edit button.
  8. In the form that opens, enable the Read permission for "Everyone (public access)".
  9. Check the "I understand the effects of these changes on my objects and buckets." checkbox.
  10. Click on the "Save changes" button.

Essential Modules Config

import { loadEnv, defineConfig, Modules } from '@medusajs/framework/utils'

loadEnv(process.env.NODE_ENV || 'development', process.cwd())

module.exports = defineConfig({
  projectConfig: {
    databaseUrl: process.env.DATABASE_URL,
    redisUrl: process.env.REDIS_URL,
    databaseLogging: false,
    http: {
      storeCors: process.env.STORE_CORS!,
      adminCors: process.env.ADMIN_CORS!,
      authCors: process.env.AUTH_CORS!,
      jwtSecret: process.env.JWT_SECRET || "supersecret",
      cookieSecret: process.env.COOKIE_SECRET || "supersecret",
    }
  },
  modules: [
    {
      key: Modules.CACHE,
      resolve: "@medusajs/cache-redis",
      options: {
        redisUrl: process.env.REDIS_URL,
        ttl: 30, // Time to live in seconds
      },
    },
    {
      key: Modules.EVENT_BUS,
      resolve: "@medusajs/event-bus-redis",
      options: {
        redisUrl: process.env.REDIS_URL,
      },
    },
    {
      key: Modules.WORKFLOW_ENGINE,
      resolve: '@medusajs/workflow-engine-redis',
      options: {
         redis: {
            url: process.env.REDIS_URL,
         },
      },
    },
    {
      key: Modules.FILE,
      resolve: "@medusajs/medusa/file",
      options: {
        providers: [
          {
            resolve: "@medusajs/medusa/file-s3",
            id: "s3",
            options: {
              file_url: process.env.S3_FILE_URL,
              access_key_id: process.env.S3_ACCESS_KEY_ID,
              secret_access_key: process.env.S3_SECRET_ACCESS_KEY,
              region: process.env.S3_REGION,
              bucket: process.env.S3_BUCKET,
              endpoint: process.env.S3_ENDPOINT,
            },
          },
        ],
      },
      ...(process.env.SENDGRID_API_KEY && process.env.SENDGRID_FROM_EMAIL ? [{
        key: Modules.NOTIFICATION,
        resolve: '@medusajs/notification',
        options: {
          providers: [
            ...(process.env.SENDGRID_API_KEY && process.env.SENDGRID_FROM_EMAIL ? [{
              resolve: '@medusajs/notification-sendgrid',
              id: 'sendgrid',
              options: {
                channels: ['email'],
                api_key: process.env.SENDGRID_API_KEY,
                from: process.env.SENDGRID_FROM_EMAIL,
              }
            }] : []),
          ]
        }
      }] : []),
      ...(process.env.STRIPE_API_KEY && process.env.STRIPE_WEBHOOK_SECRET ? [{
        key: Modules.PAYMENT,
        resolve: '@medusajs/payment',
        options: {
          providers: [
            {
              resolve: '@medusajs/payment-stripe',
              id: 'stripe',
              options: {
                apiKey: process.env.STRIPE_API_KEY,
                webhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
              },
            },
          ],
        },
      }] : [])
    },
  ],
})

Troubleshooting

Module @medusajs/cache-redis doesn't have a serviceName. Please provide a 'key' for the module or check the service joiner config.

  1. Open the medsua-config.ts file in Medusa backend repository
import { Modules } from "@medusajs/framework/utils"
//...
modules: [
{
   key: Modules.CACHE,
   resolve: "@medusajs/cache-redis",
   options: {
    redisUrl: process.env.REDIS_URL,
    ttl: 30, // Time to live in seconds
   },
},
//...

Make sure the modules used have the key

Previous
Electron