docs: general fixes and improvements (#13417)

This commit is contained in:
Shahed Nasser
2025-09-04 19:27:34 +03:00
committed by GitHub
parent 55a35e4721
commit 8785fb4e1a
5 changed files with 69 additions and 31 deletions

View File

@@ -4,14 +4,20 @@ export const metadata = {
# {metadata.title}
In the previous chapters, you've learned important concepts related to creating modules, implementing commerce features in workflows, exposing those features in API routes, customizing the Medusa Admin dashboard with Admin Extensions, and integrating third-party systems.
In the previous chapters, you've followed the [brand example](../custom-features/page.mdx) to learn important concepts related to:
You've implemented the brands example within a single Medusa application. However, this approach is not scalable when you want to reuse your customizations across multiple projects.
- [Creating modules](../custom-features/module/page.mdx).
- [Implementing commerce features in workflows](../custom-features/workflow/page.mdx).
- [Exposing those features in API routes](../custom-features/api-route/page.mdx).
- [Customizing the Medusa Admin dashboard with Admin Extensions](../customize-admin/page.mdx).
- [Integrating third-party systems](../integrate-systems/page.mdx).
To reuse your customizations across multiple Medusa applications, such as implementing brands in different projects, you can create a plugin. A plugin is an NPM package that encapsulates your customizations and can be installed in any Medusa application. Plugins can include modules, workflows, API routes, Admin Extensions, and more.
You've implemented the brands example within a single Medusa application. However, this approach is not scalable. If you want to use the same brands feature in different Medusa applications, you would have to manually copy the code and maintain it across all projects.
Instead, to reuse your customizations across multiple Medusa applications, you can create a plugin. A plugin is an NPM package that encapsulates your customizations and can be installed in any Medusa application. Plugins can include modules, workflows, API routes, Admin Extensions, and more.
![Diagram showcasing how the Brand Plugin would add its resources to any application it's installed in](https://res.cloudinary.com/dza7lstvk/image/upload/v1737540091/Medusa%20Book/brand-plugin_bk9zi9.jpg)
Medusa provides the tooling to create a plugin package, test it in a local Medusa application, and publish it to NPM.
To learn more about plugins and how to create them, refer to [this chapter](../../fundamentals/plugins/page.mdx).
Refer to the [Plugins](../../fundamentals/plugins/page.mdx) chapter to learn more about plugins and how to create them.

View File

@@ -8,11 +8,11 @@ In this chapter, you'll learn how to execute an action based on a condition in a
## Why If-Conditions Aren't Allowed in Workflows?
Medusa creates an internal representation of the workflow definition you pass to `createWorkflow` to track and store its steps. At that point, variables in the workflow don't have any values. They only do when you execute the workflow.
Medusa creates an internal representation of the workflow definition you pass to `createWorkflow` to track and store the workflow's steps. At that point, variables in the workflow don't have any values. They only do when you execute the workflow.
So, you can't use an if-condition that checks a variable's value, as the condition will be evaluated when Medusa creates the internal representation of the workflow, rather than during execution.
Instead, use when-then from the Workflows SDK. It allows you to perform steps in a workflow only if a condition that you specify is satisfied.
Instead, use `when-then` from the Workflows SDK. It allows you to perform steps in a workflow only if a condition that you specify is satisfied.
<Note title="Tip">
@@ -72,22 +72,29 @@ In this code snippet, you execute the `isActiveStep` only if the `input.is_activ
### When Parameters
`when` accepts the following parameters:
`when` accepts two parameters:
1. The first parameter is either an object or the workflow's input. This data is passed as a parameter to the function in `when`'s second parameter.
2. The second parameter is a function that returns a boolean indicating whether to execute the action in `then`.
- You can perform conditional checks or use conditional operators in this function, but only on the function's parameters.
### Then Parameters
### Then Callback Function
To specify the action to perform if the condition is satisfied, chain a `then` function to `when` and pass it a callback function.
To specify the action to perform if the condition is satisfied, chain a `then` function to `when` and pass it a callback function. The callback function is only executed if `when`'s second parameter function returns a `true` value.
The callback function is only executed if `when`'s second parameter function returns a `true` value.
The callback function passed to `then` is treated the same as the workflow's definition function. That means:
- You can execute steps in the callback function.
- You can't [transform data and variables](../variable-manipulation/page.mdx) in the callback function. Instead, use `transform`.
- You can't use if-else conditions in the callback function.
- You can't use loops in the callback function.
- You should keep in mind the [workflow constructor constraints](../constructor-constraints/page.mdx) in the callback function.
---
## Implementing If-Else with When-Then
when-then doesn't support if-else conditions. Instead, use two `when-then` conditions in your workflow.
`when-then` doesn't support if-else conditions. Instead, use two `when-then` conditions in your workflow.
For example:
@@ -166,9 +173,15 @@ const { isActive } = when(
).then(() => {
const isActive = isActiveStep()
return {
const returnData = transform({
isActive,
}
}, (data) => {
return {
message: data.isActive ? "Active" : "Not Active",
}
})
return returnData
})
```

View File

@@ -27,7 +27,7 @@ export const generatedEditDates = {
"app/learn/fundamentals/events-and-subscribers/data-payload/page.mdx": "2025-05-01T15:30:08.421Z",
"app/learn/fundamentals/workflows/advanced-example/page.mdx": "2024-09-11T10:46:59.975Z",
"app/learn/fundamentals/events-and-subscribers/emit-event/page.mdx": "2025-06-02T14:47:54.394Z",
"app/learn/fundamentals/workflows/conditions/page.mdx": "2025-01-27T08:45:19.027Z",
"app/learn/fundamentals/workflows/conditions/page.mdx": "2025-09-04T15:57:00.934Z",
"app/learn/fundamentals/modules/module-link-directions/page.mdx": "2024-07-24T09:16:01+02:00",
"app/learn/fundamentals/admin/page.mdx": "2025-07-25T12:46:15.466Z",
"app/learn/fundamentals/workflows/long-running-workflow/page.mdx": "2025-08-01T07:16:21.736Z",
@@ -102,7 +102,7 @@ export const generatedEditDates = {
"app/learn/fundamentals/workflows/store-executions/page.mdx": "2025-04-17T08:29:10.166Z",
"app/learn/fundamentals/plugins/create/page.mdx": "2025-04-17T08:29:09.910Z",
"app/learn/fundamentals/plugins/page.mdx": "2025-01-22T10:14:10.433Z",
"app/learn/customization/reuse-customizations/page.mdx": "2025-01-22T10:01:57.665Z",
"app/learn/customization/reuse-customizations/page.mdx": "2025-09-04T15:45:52.047Z",
"app/learn/update/page.mdx": "2025-01-27T08:45:19.030Z",
"app/learn/fundamentals/module-links/query-context/page.mdx": "2025-02-12T16:59:20.963Z",
"app/learn/fundamentals/admin/environment-variables/page.mdx": "2025-08-01T13:16:25.172Z",

View File

@@ -3477,17 +3477,23 @@ In the [Recipes](https://docs.medusajs.com/resources/recipes/index.html.md) docu
# Re-Use Customizations with Plugins
In the previous chapters, you've learned important concepts related to creating modules, implementing commerce features in workflows, exposing those features in API routes, customizing the Medusa Admin dashboard with Admin Extensions, and integrating third-party systems.
In the previous chapters, you've followed the [brand example](https://docs.medusajs.com/learn/customization/custom-features/index.html.md) to learn important concepts related to:
You've implemented the brands example within a single Medusa application. However, this approach is not scalable when you want to reuse your customizations across multiple projects.
- [Creating modules](https://docs.medusajs.com/learn/customization/custom-features/module/index.html.md).
- [Implementing commerce features in workflows](https://docs.medusajs.com/learn/customization/custom-features/workflow/index.html.md).
- [Exposing those features in API routes](https://docs.medusajs.com/learn/customization/custom-features/api-route/index.html.md).
- [Customizing the Medusa Admin dashboard with Admin Extensions](https://docs.medusajs.com/learn/customization/customize-admin/index.html.md).
- [Integrating third-party systems](https://docs.medusajs.com/learn/customization/integrate-systems/index.html.md).
To reuse your customizations across multiple Medusa applications, such as implementing brands in different projects, you can create a plugin. A plugin is an NPM package that encapsulates your customizations and can be installed in any Medusa application. Plugins can include modules, workflows, API routes, Admin Extensions, and more.
You've implemented the brands example within a single Medusa application. However, this approach is not scalable. If you want to use the same brands feature in different Medusa applications, you would have to manually copy the code and maintain it across all projects.
Instead, to reuse your customizations across multiple Medusa applications, you can create a plugin. A plugin is an NPM package that encapsulates your customizations and can be installed in any Medusa application. Plugins can include modules, workflows, API routes, Admin Extensions, and more.
![Diagram showcasing how the Brand Plugin would add its resources to any application it's installed in](https://res.cloudinary.com/dza7lstvk/image/upload/v1737540091/Medusa%20Book/brand-plugin_bk9zi9.jpg)
Medusa provides the tooling to create a plugin package, test it in a local Medusa application, and publish it to NPM.
To learn more about plugins and how to create them, refer to [this chapter](https://docs.medusajs.com/learn/fundamentals/plugins/index.html.md).
Refer to the [Plugins](https://docs.medusajs.com/learn/fundamentals/plugins/index.html.md) chapter to learn more about plugins and how to create them.
# Debug Workflows
@@ -18752,11 +18758,11 @@ In this chapter, you'll learn how to execute an action based on a condition in a
## Why If-Conditions Aren't Allowed in Workflows?
Medusa creates an internal representation of the workflow definition you pass to `createWorkflow` to track and store its steps. At that point, variables in the workflow don't have any values. They only do when you execute the workflow.
Medusa creates an internal representation of the workflow definition you pass to `createWorkflow` to track and store the workflow's steps. At that point, variables in the workflow don't have any values. They only do when you execute the workflow.
So, you can't use an if-condition that checks a variable's value, as the condition will be evaluated when Medusa creates the internal representation of the workflow, rather than during execution.
Instead, use when-then from the Workflows SDK. It allows you to perform steps in a workflow only if a condition that you specify is satisfied.
Instead, use `when-then` from the Workflows SDK. It allows you to perform steps in a workflow only if a condition that you specify is satisfied.
Restrictions for conditions is only applicable in a workflow's definition. You can still use if-conditions in your step's code.
@@ -18806,22 +18812,29 @@ In this code snippet, you execute the `isActiveStep` only if the `input.is_activ
### When Parameters
`when` accepts the following parameters:
`when` accepts two parameters:
1. The first parameter is either an object or the workflow's input. This data is passed as a parameter to the function in `when`'s second parameter.
2. The second parameter is a function that returns a boolean indicating whether to execute the action in `then`.
- You can perform conditional checks or use conditional operators in this function, but only on the function's parameters.
### Then Parameters
### Then Callback Function
To specify the action to perform if the condition is satisfied, chain a `then` function to `when` and pass it a callback function.
To specify the action to perform if the condition is satisfied, chain a `then` function to `when` and pass it a callback function. The callback function is only executed if `when`'s second parameter function returns a `true` value.
The callback function is only executed if `when`'s second parameter function returns a `true` value.
The callback function passed to `then` is treated the same as the workflow's definition function. That means:
- You can execute steps in the callback function.
- You can't [transform data and variables](https://docs.medusajs.com/learn/fundamentals/workflows/variable-manipulation/index.html.md) in the callback function. Instead, use `transform`.
- You can't use if-else conditions in the callback function.
- You can't use loops in the callback function.
- You should keep in mind the [workflow constructor constraints](https://docs.medusajs.com/learn/fundamentals/workflows/constructor-constraints/index.html.md) in the callback function.
***
## Implementing If-Else with When-Then
when-then doesn't support if-else conditions. Instead, use two `when-then` conditions in your workflow.
`when-then` doesn't support if-else conditions. Instead, use two `when-then` conditions in your workflow.
For example:
@@ -18890,9 +18903,15 @@ const { isActive } = when(
).then(() => {
const isActive = isActiveStep()
return {
const returnData = transform({
isActive,
}
}, (data) => {
return {
message: data.isActive ? "Active" : "Not Active",
}
})
return returnData
})
```

View File

@@ -327,7 +327,7 @@ const priceSet = await pricingModuleService.createPriceSets({
}
```
- Original price selection: The fourth price in the price list is selected as the best price.
- Original price selection: The fourth price in the price set is selected as the best price.
- Calculated price selection: since there are no associated price lists, the calculated price is set to the original price.
</TabsContent>
@@ -403,7 +403,7 @@ const priceSet = await pricingModuleService.createPriceSets({
}
```
- Original price selection: the fifth price in the price list is selected as the best price because the cart item quantity is 200.
- Original price selection: the fifth price in the price set is selected as the best price because the cart item quantity is `200`.
- This is assuming the price set belongs to the cart item's variant.
- Calculated price selection: since there are no associated price lists, the calculated price is set to the original price.
@@ -494,7 +494,7 @@ const priceSet = await pricingModuleService.createPriceSets({
}
```
- Original price selection: The fourth price in the price list is selected as the best price.
- Original price selection: The fourth price in the price set is selected as the best price.
- Calculated price selection: The first price of the price list is selected as the best price.
</TabsContent>