4.7.9. Handling CORS in API Routes

In this chapter, you’ll learn about the CORS middleware and how to configure it for custom API routes.

CORS Overview#

Cross-Origin Resource Sharing (CORS) allows only configured origins to access your API Routes.

For example, if you allow only origins starting with http://localhost:7001 to access your Admin API Routes, other origins accessing those routes get a CORS error.

CORS Configurations#

The storeCors and adminCors properties of Medusa's http configuration set the allowed origins for routes starting with /store and /admin respectively.

These configurations accept a URL pattern to identify allowed origins.

For example:

medusa-config.ts
module.exports = defineConfig({
  projectConfig: {
    http: {
      storeCors: "http://localhost:8000",
      adminCors: "http://localhost:7001",
      // ...
    },
  },
})

This allows the http://localhost:7001 origin to access the Admin API Routes, and the http://localhost:8000 origin to access Store API Routes.

Tip: Learn more about the CORS configurations in this resource guide.

CORS in Store and Admin Routes#

To disable the CORS middleware for a route, export a CORS variable in the route file with its value set to false.

For example:

src/api/store/custom/route.ts
import type { 
  MedusaRequest, 
  MedusaResponse,
} from "@medusajs/framework/http"

export const GET = (
  req: MedusaRequest,
  res: MedusaResponse
) => {
  res.json({
    message: "[GET] Hello world!",
  })
}

export const CORS = false

This disables the CORS middleware on API Routes at the path /store/custom.


CORS in Custom Routes#

If you create a route that doesn’t start with /store or /admin, you must apply the CORS middleware manually. Otherwise, all requests to your API route lead to a CORS error.

You can do that in the exported middlewares configurations in src/api/middlewares.ts.

For example:

src/api/middlewares.ts
import cors from "cors"

export default defineMiddlewares({
  routes: [
    {
      matcher: "/custom*",
      middlewares: [
        (
          req: MedusaRequest, 
          res: MedusaResponse, 
          next: MedusaNextFunction
        ) => {
          const configModule: ConfigModule =
            req.scope.resolve(
              ContainerRegistrationKeys.CONFIG_MODULE
            )

          return cors({
            origin: parseCorsOrigins(
              configModule.projectConfig.http.storeCors
            ),
            credentials: true,
          })(req, res, next)
        },
      ],
    },
  ],
})

This retrieves the configurations exported from medusa-config.ts and applies the storeCors to routes starting with /custom.

Was this chapter helpful?
Ask Bloom
For assistance in your development, use Claude Code Plugins or Docs MCP server in Cursor, VSCode, etc...FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break
⇧↵