docs: improve CORS troubleshooting guide (#14194)
This commit is contained in:
@@ -1641,10 +1641,10 @@ import { createOptionsInStrapiStep } from "./steps/create-options-in-strapi"
|
||||
import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
|
||||
import {
|
||||
CreateOptionValuesInStrapiInput,
|
||||
createOptionValuesInStrapiStep
|
||||
createOptionValuesInStrapiStep,
|
||||
} from "./steps/create-option-values-in-strapi"
|
||||
import {
|
||||
updateProductOptionValuesMetadataStep
|
||||
updateProductOptionValuesMetadataStep,
|
||||
} from "./steps/update-product-option-values-metadata"
|
||||
|
||||
export type CreateOptionsInStrapiWorkflowInput = {
|
||||
@@ -2121,7 +2121,7 @@ export const createVariantsInStrapiWorkflow = createWorkflow(
|
||||
})
|
||||
|
||||
const strapiVariants = when({
|
||||
variants
|
||||
variants,
|
||||
}, (data) => !!(data.variants[0].product as any)?.strapi_product)
|
||||
.then(() => {
|
||||
const variantImages = transform({
|
||||
@@ -2158,7 +2158,7 @@ export const createVariantsInStrapiWorkflow = createWorkflow(
|
||||
const variantsData = transform({
|
||||
variants,
|
||||
strapiVariantImages,
|
||||
strapiVariantThumbnail
|
||||
strapiVariantThumbnail,
|
||||
}, (data) => {
|
||||
const varData = data.variants.map((variant) => ({
|
||||
id: variant.id,
|
||||
@@ -2939,7 +2939,7 @@ export const handleStrapiWebhookWorkflow = createWorkflow(
|
||||
const variants = updateProductVariantsWorkflow.runAsStep({
|
||||
input: {
|
||||
product_variants: [
|
||||
preparedData.data as unknown as UpsertProductVariantDTO
|
||||
preparedData.data as unknown as UpsertProductVariantDTO,
|
||||
],
|
||||
},
|
||||
})
|
||||
@@ -2988,7 +2988,7 @@ export const handleStrapiWebhookWorkflow = createWorkflow(
|
||||
// Clear the product cache for all affected products
|
||||
const productIds = transform({ variants }, (data) => {
|
||||
const uniqueProductIds = [
|
||||
...new Set(data.variants.map((v) => v.product_id))
|
||||
...new Set(data.variants.map((v) => v.product_id)),
|
||||
]
|
||||
return uniqueProductIds as string[]
|
||||
})
|
||||
@@ -3815,7 +3815,7 @@ Then, find the `Text` component wrapping the `{product.description}` and replace
|
||||
>
|
||||
<Markdown
|
||||
allowedElements={[
|
||||
"p", "ul", "ol", "li", "strong", "em", "blockquote", "hr", "br", "a"
|
||||
"p", "ul", "ol", "li", "strong", "em", "blockquote", "hr", "br", "a",
|
||||
]}
|
||||
unwrapDisallowed
|
||||
>
|
||||
|
||||
@@ -1,22 +1,104 @@
|
||||
If you are experiencing connection issues when trying to access your Medusa application from a storefront or the admin dashboard, it is most likely due to Cross-Origin Resource Sharing (CORS) issues.
|
||||
If you're experiencing connection issues when trying to access your Medusa application's API routes from the storefront, admin dashboard, or any client application, it's most likely due to a Cross-Origin Resource Sharing (CORS) error.
|
||||
|
||||
You might see a log in your browser console, that looks like this:
|
||||
To verify it's a CORS error, check your [browser's console](https://developer.mozilla.org/en-US/docs/Learn_web_development/Howto/Tools_and_setup/What_are_browser_developer_tools). You should see an error similar to the following:
|
||||
|
||||

|
||||
```bash
|
||||
Access to fetch at 'http://localhost:9000/store/products' from origin 'http://localhost:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
|
||||
```
|
||||
|
||||
In your `medusa-config.ts`, ensure that you've configured your CORS settings correctly:
|
||||
## Why this Error Occurred
|
||||
|
||||
This error occurs when you try to access the Medusa server's API routes from a domain that isn't configured in the application's CORS settings. By default, Medusa only allows requests from specific origins to ensure security.
|
||||
|
||||
---
|
||||
|
||||
## How to Fix It
|
||||
|
||||
### Verify Your CORS Settings
|
||||
|
||||
Medusa has three CORS settings that you can configure in your `medusa-config.ts` file:
|
||||
|
||||
1. [http.storeCors](!docs!/learn/configurations/medusa-config#httpstorecors): Allowed origins for requests to routes starting with `/store`. By default, it's set to `http://localhost:8000` for local development.
|
||||
2. [http.adminCors](!docs!/learn/configurations/medusa-config#httpadmincors): Allowed origins for requests to routes starting with `/admin`. By default, it's set to `http://localhost:9000` for local development.
|
||||
3. [http.authCors](!docs!/learn/configurations/medusa-config#httpauthcors): Allowed origins for requests to routes starting with `/auth`. By default, it's set to `http://localhost:8000,http://localhost:9000` for local development.
|
||||
|
||||
If your storefront or admin are hosted at different domains or ports, or if you're accessing Medusa's API routes from a different origin (such as an additional storefront), you'll need to update the CORS settings accordingly. You can add additional origins by separating them with commas.
|
||||
|
||||
For example, set the following environment variables in your `.env` file or in [Cloud](!cloud!/environments/environment-variables):
|
||||
|
||||
```env
|
||||
STORE_CORS=http://localhost:8000,http://my-custom-store.com
|
||||
ADMIN_CORS=http://localhost:9000,http://my-custom-admin.com
|
||||
AUTH_CORS=http://localhost:8000,http://localhost:9000,http://my-custom-store.com,http://my-custom-admin.com
|
||||
```
|
||||
|
||||
Then use the environment variables in your `medusa-config.ts` file:
|
||||
|
||||
```ts title="medusa-config.ts"
|
||||
module.exports = defineConfig({
|
||||
projectConfig: {
|
||||
http: {
|
||||
storeCors: process.env.STORE_CORS || "http://localhost:8000",
|
||||
adminCors: process.env.ADMIN_CORS || "http://localhost:9000",
|
||||
authCors: process.env.AUTH_CORS || "http://localhost:8000,http://localhost:9000",
|
||||
storeCors: process.env.STORE_CORS,
|
||||
adminCors: process.env.ADMIN_CORS,
|
||||
authCors: process.env.AUTH_CORS,
|
||||
},
|
||||
// ...
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Learn more about these configurations in [this documentation](!docs!/learn/configurations/medusa-config#http).
|
||||
### Apply CORS for Custom Route Prefix
|
||||
|
||||
Medusa applies its CORS settings to routes starting with `/store`, `/admin`, and `/auth`. If you've created a route whose path doesn't start with one of these prefixes, you must manually handle CORS for that route.
|
||||
|
||||
For example, if you create a custom route at `/custom-routes`, add a middleware to handle CORS for that route:
|
||||
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import { defineMiddlewares } from "@medusajs/framework/http"
|
||||
import type {
|
||||
MedusaNextFunction,
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "@medusajs/framework/http"
|
||||
import { ConfigModule } from "@medusajs/framework/types"
|
||||
import { parseCorsOrigins } from "@medusajs/framework/utils"
|
||||
import cors from "cors"
|
||||
|
||||
export default defineMiddlewares({
|
||||
routes: [
|
||||
{
|
||||
matcher: "/custom-routes*",
|
||||
middlewares: [
|
||||
(
|
||||
req: MedusaRequest,
|
||||
res: MedusaResponse,
|
||||
next: MedusaNextFunction
|
||||
) => {
|
||||
const configModule: ConfigModule =
|
||||
req.scope.resolve("configModule")
|
||||
|
||||
return cors({
|
||||
origin: parseCorsOrigins(
|
||||
// Use the appropriate CORS setting for your custom route
|
||||
configModule.projectConfig.http.storeCors
|
||||
),
|
||||
credentials: true,
|
||||
})(req, res, next)
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
Make sure to:
|
||||
|
||||
- Update the `matcher` property to match your custom route path.
|
||||
- Pass the appropriate CORS setting for your custom route to `parseCorsOrigins`.
|
||||
|
||||
---
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Medusa Configuration Options](!docs!/learn/configurations/medusa-config)
|
||||
- [CORS for Custom Routes](!docs!/learn/fundamentals/api-routes/cors#cors-in-custom-routes)
|
||||
@@ -5356,14 +5356,6 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/confirmClaimRequestWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "confirmDraftOrderEditWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/confirmDraftOrderEditWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -5396,6 +5388,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/confirmVariantInventoryWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "convertDraftOrderWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/convertDraftOrderWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -6733,6 +6733,22 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/completeOrderWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "computeAdjustmentsForPreviewWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/computeAdjustmentsForPreviewWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "computeDraftOrderAdjustmentsWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/computeDraftOrderAdjustmentsWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -6949,6 +6965,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/maybeRefreshShippingMethodsWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "onCarryPromotionsFlagSet",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/onCarryPromotionsFlagSet",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -7277,6 +7301,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateOrderChangesWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "updateOrderChangeWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateOrderChangeWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -13687,6 +13719,30 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"autogenerate_as_ref": true,
|
||||
"sort_sidebar": "alphabetize",
|
||||
"children": [
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "addDraftOrderItemsWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/addDraftOrderItemsWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "addDraftOrderPromotionWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/addDraftOrderPromotionWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "addDraftOrderShippingMethodsWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/addDraftOrderShippingMethodsWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -13719,6 +13775,22 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/batchPromotionRulesWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "computeAdjustmentsForPreviewWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/computeAdjustmentsForPreviewWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "computeDraftOrderAdjustmentsWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/computeDraftOrderAdjustmentsWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -13783,6 +13855,46 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/deletePromotionsWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "onCarryPromotionsFlagSet",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/onCarryPromotionsFlagSet",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "orderEditAddNewItemWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/orderEditAddNewItemWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "orderEditUpdateItemQuantityWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/orderEditUpdateItemQuantityWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "orderExchangeAddNewItemWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/orderExchangeAddNewItemWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "orderExchangeRequestItemReturnWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/orderExchangeRequestItemReturnWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -13791,6 +13903,46 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/refreshCartItemsWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "removeDraftOrderActionItemWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/removeDraftOrderActionItemWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "removeDraftOrderActionShippingMethodWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/removeDraftOrderActionShippingMethodWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "removeDraftOrderPromotionsWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/removeDraftOrderPromotionsWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "removeDraftOrderShippingMethodWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/removeDraftOrderShippingMethodWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "removeItemOrderEditActionWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/removeItemOrderEditActionWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -13823,6 +13975,46 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateCartWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "updateDraftOrderActionItemWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateDraftOrderActionItemWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "updateDraftOrderActionShippingMethodWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateDraftOrderActionShippingMethodWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "updateDraftOrderItemWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateDraftOrderItemWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "updateDraftOrderShippingMethodWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateDraftOrderShippingMethodWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "updateExchangeAddItemWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateExchangeAddItemWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
@@ -13831,6 +14023,30 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateLineItemInCartWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "updateOrderChangeWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateOrderChangeWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "updateOrderEditAddItemWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateOrderEditAddItemWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "ref",
|
||||
"title": "updateOrderEditItemQuantityWorkflow",
|
||||
"path": "https://docs.medusajs.com/resources/references/medusa-workflows/updateOrderEditItemQuantityWorkflow",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
|
||||
Reference in New Issue
Block a user