docs: revise main docs outline (#10502)
This commit is contained in:
4
.github/workflows/docs-test.yml
vendored
4
.github/workflows/docs-test.yml
vendored
@@ -41,9 +41,9 @@ jobs:
|
||||
NEXT_PUBLIC_BASE_URL: "http://localhost:3000"
|
||||
NEXT_PUBLIC_BASE_PATH: /api
|
||||
NEXT_PUBLIC_DOCS_URL: "https://medusa-docs.vercel.app"
|
||||
NEXT_PUBLIC_UI_URL: "https://docs-ui.vercel.app"
|
||||
NODE_ENV: production
|
||||
NEXT_PUBLIC_RESOURCES_URL: "http://medusa-types-nine.vercel.app"
|
||||
# TODO change once we have actual URLs
|
||||
NEXT_PUBLIC_RESOURCES_URL: "http://example.com"
|
||||
NEXT_PUBLIC_USER_GUIDE_URL: "http://example.com"
|
||||
|
||||
vale-book:
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} API Routes Advanced Guides`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In the next chapters, you'll focus more on API routes to learn about topics such as:
|
||||
|
||||
- Creating API routes for different HTTP methods.
|
||||
- Accepting parameters in your API routes.
|
||||
- Formatting response data and headers.
|
||||
- Applying middlewares on API routes.
|
||||
- Validating request body parameters.
|
||||
- Protecting API routes by requiring user authentication.
|
||||
@@ -1,15 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Modules Advanced Guides`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In the next chapters, you'll learn more about developing modules and related resources.
|
||||
|
||||
By the end of this chapter, you'll know more about:
|
||||
|
||||
1. A module's container and how a module is isolated.
|
||||
2. Passing options to a module.
|
||||
3. The service factory and the methods it generates.
|
||||
4. Using a module's service to query and perform actions on the database.
|
||||
5. Using multiple services in a module.
|
||||
@@ -1,15 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Advanced Development`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In the previous chapters, you got a brief introduction to Medusa’s basic concepts. However, to build a custom commerce application, you need a deeper understanding of how you utilize these concepts for your business use case.
|
||||
|
||||
The next chapters dive deeper into each concept, and explore Medusa's architecture. By the end of these chapters, you’ll be able to:
|
||||
|
||||
- Expose API routes with control over authentication.
|
||||
- Build sophisticated business logic in modules and manage links between them.
|
||||
- Create advanced workflows and configure retries and timeout.
|
||||
- Add new pages to the Medusa Admin.
|
||||
- Do more with subscribers, scheduled jobs, and other tools.
|
||||
@@ -1,14 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Workflows Advanced Development`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In the next chapters, you'll learn about workflows in-depth and how to use them in your custom development.
|
||||
|
||||
By the end of these chapters, you'll learn about:
|
||||
|
||||
- Constructing a workflow and its constraints.
|
||||
- Using a compensation function to undo a step's action when errors occur.
|
||||
- Hooks and how to consume and expose them.
|
||||
- Configurations to retry workflows or run them in the background.
|
||||
@@ -1,64 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Admin Customizations`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn how to customize the Medusa Admin dashboard.
|
||||
|
||||
## What is the Medusa Admin?
|
||||
|
||||
The Medusa Admin is an admin dashboard that merchants use to manage their store's data.
|
||||
|
||||
You can extend the Medusa Admin to add widgets and new pages. In your customizations, you interact with API routes to provide merchants with custom functionalities.
|
||||
|
||||
The Medusa Admin is installed in your Medusa application and runs at `http://localhost:9000/app` when you start the application.
|
||||
|
||||
---
|
||||
|
||||
## Example: Create a Widget
|
||||
|
||||
A widget is a React component that can be injected into an existing page in the admin dashboard.
|
||||
|
||||
For example, create the file `src/admin/widgets/product-widget.tsx` with the following content:
|
||||
|
||||
```tsx title="src/admin/widgets/product-widget.tsx"
|
||||
import { defineWidgetConfig } from "@medusajs/admin-sdk"
|
||||
import { Container, Heading } from "@medusajs/ui"
|
||||
|
||||
const ProductWidget = () => {
|
||||
return (
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h2">Product Widget</Heading>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export const config = defineWidgetConfig({
|
||||
zone: "product.details.before",
|
||||
})
|
||||
|
||||
export default ProductWidget
|
||||
```
|
||||
|
||||
This inserts a widget with the text “Product Widget” at the beginning of a product’s details page.
|
||||
|
||||
In your widget, use custom components from the [Medusa UI package](https://docs.medusajs.com/ui).
|
||||
|
||||
### Test the Widget
|
||||
|
||||
To test out the widget, start the Medusa application:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Then, open a product’s details page in the Medusa Admin. You’ll find your custom widget at the top of the page.
|
||||
|
||||
---
|
||||
|
||||
## Admin Components List
|
||||
|
||||
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-components) to find common components.
|
||||
@@ -1,18 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} The Basics`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In the next chapters, you’ll learn about the basic concepts of Medusa that are central to your development.
|
||||
|
||||
By the end of these chapters, you’ll be able to:
|
||||
|
||||
- Expose your custom functionalities through endpoints.
|
||||
- Create custom modules that define custom business logic.
|
||||
- Create custom tables in the database through data models.
|
||||
- Execute scripts when the Medusa application starts.
|
||||
- Perform asynchronous actions when an event occurs.
|
||||
- Run tasks at a specified time or pattern during the Medusa application's runtime.
|
||||
- Create custom flows as a series of steps involving multiple services.
|
||||
- Customize the admin dashboard to inject components on existing pages or add new pages.
|
||||
@@ -1,26 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Project File Conventions`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll learn about important directories and files in your Medusa application's project.
|
||||
|
||||

|
||||
|
||||
## src
|
||||
|
||||
This directory is the central place for your custom development. It includes the following sub-directories:
|
||||
|
||||
- `admin`: Holds your admin dashboard's custom [widgets](../../advanced-development/admin/widgets/page.mdx) and [UI routes](../../advanced-development/admin/ui-routes/page.mdx).
|
||||
- `api`: Holds your custom [API routes](../api-routes/page.mdx) that are added as endpoints in your Medusa application.
|
||||
- `jobs`: Holds your [scheduled jobs](../scheduled-jobs/page.mdx) that run at a specified interval during your Medusa application's runtime.
|
||||
- `links`: Holds you [module links](../../advanced-development/module-links/page.mdx) that build associations between data models of different modules.
|
||||
- `modules`: Holds your custom [modules](../modules/page.mdx) that implement custom business logic.
|
||||
- `scripts`: Holds your custom [scripts](../../advanced-development/custom-cli-scripts/page.mdx) to be executed using Medusa's CLI tool.
|
||||
- `subscribers`: Holds your [event listeners](../events-and-subscribers/page.mdx) that are executed asynchronously whenever an event is emitted.
|
||||
- `workflows`: Holds your custom [flows](../workflows/page.mdx) that can be executed from anywhere in your application.
|
||||
|
||||
## medusa-config.ts
|
||||
|
||||
This file holds your [Medusa configurations](!resources!/references/medusa-config), such as your PostgreSQL database configurations.
|
||||
@@ -55,7 +55,7 @@ cp ../../.env .env.production
|
||||
|
||||
<Note>
|
||||
|
||||
When `NODE_ENV=production`, the Medusa application loads the environment variables from `.env.production`. Learn more about environment variables in [this guide](../advanced-development/environment-variables/page.mdx).
|
||||
When `NODE_ENV=production`, the Medusa application loads the environment variables from `.env.production`. Learn more about environment variables in [this guide](../fundamentals/environment-variables/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ You create an API route in a `route.{ts,js}` file under a sub-directory of the `
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about API routes [in this guide](../../../basics/api-routes/page.mdx).
|
||||
Learn more about API routes [in this guide](../../../fundamentals/api-routes/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -63,7 +63,7 @@ export const POST = async (
|
||||
|
||||
You export a route handler function with its name (`POST`) being the HTTP method of the API route you're exposing.
|
||||
|
||||
The function receives two parameters: a `MedusaRequest` object to access request details, and `MedusaResponse` object to return or manipulate the response. The `MedusaRequest` object's `scope` property is the [Medusa container](../../../basics/medusa-container/page.mdx) that holds framework tools and custom and core modules' services.
|
||||
The function receives two parameters: a `MedusaRequest` object to access request details, and `MedusaResponse` object to return or manipulate the response. The `MedusaRequest` object's `scope` property is the [Medusa container](../../../fundamentals/medusa-container/page.mdx) that holds framework tools and custom and core modules' services.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
@@ -85,7 +85,7 @@ Medusa uses [Zod](https://zod.dev/) to create validation schemas. These schemas
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about API route validation in [this chapter](../../../advanced-development/api-routes/validation/page.mdx).
|
||||
Learn more about API route validation in [this chapter](../../../fundamentals/api-routes/validation/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -123,7 +123,7 @@ A middleware is a function executed before the route handler when a request is s
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about middlewares in [this chapter](../../../advanced-development/api-routes/middlewares/page.mdx).
|
||||
Learn more about middlewares in [this chapter](../../../fundamentals/api-routes/middlewares/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ In a module, you create data models and business logic to manage them. In the ne
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about modules in [this chapter](../../../basics/modules/page.mdx).
|
||||
Learn more about modules in [this chapter](../../../fundamentals/modules/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -30,7 +30,7 @@ A data model represents a table in the database. You create data models using Me
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about data models in [this chapter](../../../basics/modules/page.mdx#1-create-data-model).
|
||||
Learn more about data models in [this chapter](../../../fundamentals/modules/page.mdx#1-create-data-model).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -56,7 +56,7 @@ You define the data model using the `define` method of the `model` utility impor
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Learn about other property types in [this chapter](../../../advanced-development/data-models/property-types/page.mdx).
|
||||
Learn about other property types in [this chapter](../../../fundamentals/data-models/property-types/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -70,7 +70,7 @@ In this step, you'll create the Brand Module's service that provides methods to
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about services in [this chapter](../../../basics/modules/page.mdx#2-create-service).
|
||||
Learn more about services in [this chapter](../../../fundamentals/modules/page.mdx#2-create-service).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -168,7 +168,7 @@ A migration is a TypeScript or JavaScript file that defines database changes mad
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about migrations in [this chapter](../../../basics/modules/page.mdx#5-generate-migrations).
|
||||
Learn more about migrations in [this chapter](../../../fundamentals/modules/page.mdx#5-generate-migrations).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ By following these guides, you'll add brands to the Medusa application that you
|
||||
|
||||
To build a custom feature in Medusa, you need three main tools:
|
||||
|
||||
- [Module](../../basics/modules/page.mdx): a package with commerce logic for a single domain. It defines new tables to add to the database, and a class of methods to manage these tables.
|
||||
- [Workflow](../../basics/workflows/page.mdx): a tool to perform an operation comprising multiple steps with built-in rollback and retry mechanisms.
|
||||
- [API route](../../basics/api-routes/page.mdx): a REST endpoint that exposes commerce features to clients, such as the admin dashboard or a storefront. The API route executes a workflow that implements the commerce feature using modules.
|
||||
- [Module](../../fundamentals/modules/page.mdx): a package with commerce logic for a single domain. It defines new tables to add to the database, and a class of methods to manage these tables.
|
||||
- [Workflow](../../fundamentals/workflows/page.mdx): a tool to perform an operation comprising multiple steps with built-in rollback and retry mechanisms.
|
||||
- [API route](../../fundamentals/api-routes/page.mdx): a REST endpoint that exposes commerce features to clients, such as the admin dashboard or a storefront. The API route executes a workflow that implements the commerce feature using modules.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ The workflow you'll create in this chapter will use the Brand Module's service t
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about workflows in [this chapter](../../../basics/workflows/page.mdx).
|
||||
Learn more about workflows in [this chapter](../../../fundamentals/workflows/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -67,7 +67,7 @@ You create a `createBrandStep` using the `createStep` function. It accepts the s
|
||||
|
||||
The step function receives two parameters: input passed to the step when it's invoked, and an object of general context and configurations. This object has a `container` property, which is the Medusa container.
|
||||
|
||||
The [Medusa container](../../../basics/medusa-container/page.mdx) is a registry of framework and commerce tools accessible in your customizations, such as a workflow's step. The Medusa application registers the services of core and custom modules in the container, allowing you to resolve and use them.
|
||||
The [Medusa container](../../../fundamentals/medusa-container/page.mdx) is a registry of framework and commerce tools accessible in your customizations, such as a workflow's step. The Medusa application registers the services of core and custom modules in the container, allowing you to resolve and use them.
|
||||
|
||||
So, In the step function, you use the Medusa container to resolve the Brand Module's service and use its generated `createBrands` method, which accepts an object of brands to create.
|
||||
|
||||
@@ -85,7 +85,7 @@ You define for each step a compensation function that's executed when an error o
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about the compensation function in [this chapter](../../../advanced-development/workflows/compensation-function/page.mdx).
|
||||
Learn more about the compensation function in [this chapter](../../../fundamentals/workflows/compensation-function/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ In the previous chapters, you've customized your Medusa application to [add bran
|
||||
|
||||
After customizing and extending your application with new features, you may need to provide an interface for admin users to utilize these features. The Medusa Admin dashboard is extendable, allowing you to:
|
||||
|
||||
- Insert components, called [widgets](../../advanced-development/admin/widgets/page.mdx), on existing pages.
|
||||
- Add new pages, called [UI Routes](../../advanced-development/admin/ui-routes/page.mdx).
|
||||
- Insert components, called [widgets](../../fundamentals/admin/widgets/page.mdx), on existing pages.
|
||||
- Add new pages, called [UI Routes](../../fundamentals/admin/ui-routes/page.mdx).
|
||||
|
||||
From these customizations, you can send requests to custom API routes, allowing admin users to manage custom resources on the dashboard
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ In this chapter, you'll add a UI route to the admin dashboard that shows the all
|
||||
|
||||
## 1. Get Brands API Route
|
||||
|
||||
In a [previous chapter](../../extend-features/query-linked-records/page.mdx), you learned how to add an API route that retrieves brands and their products using [Query](../../../advanced-development/module-links/query/page.mdx). You'll expand that API route to support pagination, so that on the admin dashboard you can show the brands in a paginated table.
|
||||
In a [previous chapter](../../extend-features/query-linked-records/page.mdx), you learned how to add an API route that retrieves brands and their products using [Query](../../../fundamentals/module-links/query/page.mdx). You'll expand that API route to support pagination, so that on the admin dashboard you can show the brands in a paginated table.
|
||||
|
||||
Replace or create the `GET` API route at `src/api/admin/brands/route.ts` with the following:
|
||||
|
||||
@@ -76,7 +76,7 @@ You return in the response the retrieved brands and the pagination configuration
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about pagination with Query in [this chapter](../../../advanced-development/module-links/query/page.mdx#apply-pagination).
|
||||
Learn more about pagination with Query in [this chapter](../../../fundamentals/module-links/query/page.mdx#apply-pagination).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -138,7 +138,7 @@ By applying the above middleware, you can pass pagination configurations to `GET
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about using the `validateAndTransformQuery` middleware to configure Query in [this chapter](../../../advanced-development/module-links/query/page.mdx#request-query-configurations).
|
||||
Learn more about using the `validateAndTransformQuery` middleware to configure Query in [this chapter](../../../fundamentals/module-links/query/page.mdx#request-query-configurations).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -186,7 +186,7 @@ You'll now add the UI route that shows the paginated list of brands. A UI route
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about UI routes in [this chapter](../../../advanced-development/admin/ui-routes/page.mdx).
|
||||
Learn more about UI routes in [this chapter](../../../fundamentals/admin/ui-routes/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ You'll now add a widget to the product-details page. A widget is a React compone
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about widgets in [this documentation](../../../advanced-development/admin/widgets/page.mdx).
|
||||
Learn more about widgets in [this documentation](../../../fundamentals/admin/widgets/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ export const metadata = {
|
||||
|
||||
In this chapter, you'll learn how to define a module link between a brand defined in the [custom Brand Module](../../custom-features/module/page.mdx), and a product defined in the [Product Module](!resources!/commerce-modules/product) that's available in your Medusa application out-of-the-box.
|
||||
|
||||
Modules are [isolated](../../../advanced-development/modules/isolation/page.mdx) from other resources, ensuring that they're integrated into the Medusa application without side effects. However, you may need to associate data models of different modules, or you're trying to extend data models from commerce modules with custom properties. To do that, you define module links.
|
||||
Modules are [isolated](../../../fundamentals/modules/isolation/page.mdx) from other resources, ensuring that they're integrated into the Medusa application without side effects. However, you may need to associate data models of different modules, or you're trying to extend data models from commerce modules with custom properties. To do that, you define module links.
|
||||
|
||||
A module link forms an association between two data models of different modules while maintaining module isolation. You can then manage and query linked records of the data models using Medusa's Modules SDK.
|
||||
|
||||
@@ -16,7 +16,7 @@ In this chapter, you'll define a module link between the `Brand` data model of t
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about module links in [this chapters](../../../advanced-development/module-links/page.mdx).
|
||||
Learn more about module links in [this chapters](../../../fundamentals/module-links/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ export const metadata = {
|
||||
|
||||
After linking the [custom Brand data model](../../custom-features/module/page.mdx) and Medusa's [Product Module](!resources!/commerce-modules/product) in the [previous chapter](../define-link/page.mdx), you'll extend the create product workflow and API route to allow associating a brand with a product.
|
||||
|
||||
Some API routes, including the [Create Product API route](!api!/admin#products_postproducts), accept an `additional_data` request body parameter. This parameter can hold custom data that's passed to the [hooks](../../../advanced-development/workflows/workflow-hooks/page.mdx) of the workflow executed in the API route, allowing you to consume those hooks and perform actions with the custom data.
|
||||
Some API routes, including the [Create Product API route](!api!/admin#products_postproducts), accept an `additional_data` request body parameter. This parameter can hold custom data that's passed to the [hooks](../../../fundamentals/workflows/workflow-hooks/page.mdx) of the workflow executed in the API route, allowing you to consume those hooks and perform actions with the custom data.
|
||||
|
||||
So, in this chapter, to extend the create product flow and associate a brand with a product, you will:
|
||||
|
||||
@@ -17,7 +17,7 @@ So, in this chapter, to extend the create product flow and associate a brand wit
|
||||
|
||||
<Note>
|
||||
|
||||
To learn more about the `additional_data` property and the API routes that accept additional data, refer to [this chapter](../../../advanced-development/api-routes/additional-data/page.mdx).
|
||||
To learn more about the `additional_data` property and the API routes that accept additional data, refer to [this chapter](../../../fundamentals/api-routes/additional-data/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -42,7 +42,7 @@ A workflow hook is a point in a workflow where you can inject a step to perform
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about the workflow hooks in [this chapter](../../../advanced-development/workflows/workflow-hooks/page.mdx).
|
||||
Learn more about the workflow hooks in [this chapter](../../../fundamentals/workflows/workflow-hooks/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -87,7 +87,7 @@ createProductsWorkflow.hooks.productsCreated(
|
||||
Workflows have a special `hooks` property to access its hooks and consume them. Each hook, such as `productCreated`, accepts a step function as a parameter. The step function accepts the following parameters:
|
||||
|
||||
1. An object having an `additional_data` property, which is the custom data passed in the request body under `additional_data`. The object will also have properties passed from the workflow to the hook, which in this case is the `products` property that holds an array of the created products.
|
||||
2. An object of properties related to the step's context. It has a `container` property whose value is the [Medusa container](../../../basics/medusa-container/page.mdx) to resolve framework and commerce tools.
|
||||
2. An object of properties related to the step's context. It has a `container` property whose value is the [Medusa container](../../../fundamentals/medusa-container/page.mdx) to resolve framework and commerce tools.
|
||||
|
||||
In the step, if a brand ID is passed in `additional_data`, you resolve the Brand Module's service and use its generated `retrieveBrand` method to retrieve the brand by its ID. The `retrieveBrand` method will throw an error if the brand doesn't exist.
|
||||
|
||||
@@ -97,7 +97,7 @@ Next, you want to create a link between the created products and the brand. To d
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about the remote link in [this chapter](../../../advanced-development/module-links/remote-link/page.mdx).
|
||||
Learn more about the remote link in [this chapter](../../../fundamentals/module-links/remote-link/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ In other commerce platforms, you extend core features and models through hacky w
|
||||
|
||||
Medusa's framework and orchestration tools mitigate these issues while supporting all your customization needs:
|
||||
|
||||
- [Module Links](../../advanced-development/module-links/page.mdx): Link data models of different modules without building direct dependencies, ensuring that the Medusa application integrates your modules without side effects.
|
||||
- [Workflow Hooks](../../advanced-development/workflows/workflow-hooks/page.mdx): inject custom functionalities into a workflow at predefined points, called hooks. This allows you to perform custom actions as a part of a core workflow without hacky workarounds.
|
||||
- [Additional Data in API Routes](../../advanced-development/api-routes/additional-data/page.mdx): Configure core API routes to accept request parameters relevant to your customizations. These parameters are passed to the underlying workflow's hooks, where you can manage your custom data as part of an existing flow.
|
||||
- [Module Links](../../fundamentals/module-links/page.mdx): Link data models of different modules without building direct dependencies, ensuring that the Medusa application integrates your modules without side effects.
|
||||
- [Workflow Hooks](../../fundamentals/workflows/workflow-hooks/page.mdx): inject custom functionalities into a workflow at predefined points, called hooks. This allows you to perform custom actions as a part of a core workflow without hacky workarounds.
|
||||
- [Additional Data in API Routes](../../fundamentals/api-routes/additional-data/page.mdx): Configure core API routes to accept request parameters relevant to your customizations. These parameters are passed to the underlying workflow's hooks, where you can manage your custom data as part of an existing flow.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ You can also retrieve linked records using Query. Query allows you to retrieve d
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about Query in [this chapter](../../../advanced-development/module-links/query/page.mdx).
|
||||
Learn more about Query in [this chapter](../../../fundamentals/module-links/query/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ In the [previous chapter](../service/page.mdx), you created a CMS Module that in
|
||||
|
||||
In another previous chapter, you [added a workflow](../../custom-features/workflow/page.mdx) that creates a brand. After integrating the CMS, you want to sync that brand to the third-party system as well.
|
||||
|
||||
Medusa has an event system that emits events when an operation is performed. It allows you to listen to those events and perform an asynchronous action in a function called a [subscriber](../../../basics/events-and-subscribers/page.mdx). This is useful to perform actions that aren't integral to the original flow, such as syncing data to a third-party system.
|
||||
Medusa has an event system that emits events when an operation is performed. It allows you to listen to those events and perform an asynchronous action in a function called a [subscriber](../../../fundamentals/events-and-subscribers/page.mdx). This is useful to perform actions that aren't integral to the original flow, such as syncing data to a third-party system.
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about Medusa's event system and subscribers in [this chapter](../../../basics/events-and-subscribers/page.mdx).
|
||||
Learn more about Medusa's event system and subscribers in [this chapter](../../../fundamentals/events-and-subscribers/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -87,13 +87,13 @@ Workflows have a built-in durable execution engine that helps you complete tasks
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about workflows in [this chapter](../../../basics/workflows/page.mdx).
|
||||
Learn more about workflows in [this chapter](../../../fundamentals/workflows/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
You'll create a `syncBrandToSystemWorkflow` that has two steps:
|
||||
|
||||
- `useQueryGraphStep`: a step that Medusa provides to retrieve data using [Query](../../../advanced-development/module-links/query/page.mdx). You'll use this to retrieve the brand's details using its ID.
|
||||
- `useQueryGraphStep`: a step that Medusa provides to retrieve data using [Query](../../../fundamentals/module-links/query/page.mdx). You'll use this to retrieve the brand's details using its ID.
|
||||
- `syncBrandToCmsStep`: a step that you'll create to sync the brand to the CMS.
|
||||
|
||||
### syncBrandToCmsStep
|
||||
@@ -142,13 +142,13 @@ const syncBrandToCmsStep = createStep(
|
||||
)
|
||||
```
|
||||
|
||||
You create the `syncBrandToCmsStep` that accepts a brand as an input. In the step, you resolve the CMS Module's service from the [Medusa container](../../../basics/medusa-container/page.mdx) and use its `createBrand` method. This method will create the brand in the third-party CMS.
|
||||
You create the `syncBrandToCmsStep` that accepts a brand as an input. In the step, you resolve the CMS Module's service from the [Medusa container](../../../fundamentals/medusa-container/page.mdx) and use its `createBrand` method. This method will create the brand in the third-party CMS.
|
||||
|
||||
You also pass the brand's ID to the step's compensation function. In this function, you delete the brand in the third-party CMS if an error occurs during the workflow's execution.
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about compensation functions in [this chapter](../../../advanced-development/workflows/compensation-function/page.mdx).
|
||||
Learn more about compensation functions in [this chapter](../../../fundamentals/workflows/compensation-function/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -270,7 +270,7 @@ In the function, you execute the `syncBrandToCmsWorkflow`, passing it the data p
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about subscribers in [this chapter](../../../basics/events-and-subscribers/page.mdx).
|
||||
Learn more about subscribers in [this chapter](../../../fundamentals/events-and-subscribers/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ In Medusa, you integrate a third-party system by:
|
||||
|
||||
1. Creating a module whose service provides the methods to connect to and perform operations in the third-party system.
|
||||
2. Building workflows that complete tasks spanning across systems. You use the module that integrates a third-party system in the workflow's steps.
|
||||
3. Executing the workflows you built in an [API route](../../basics/api-routes/page.mdx), at a scheduled time, or when an event is emitted.
|
||||
3. Executing the workflows you built in an [API route](../../fundamentals/api-routes/page.mdx), at a scheduled time, or when an event is emitted.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ You can create an action to be automatically executed at a specified interval us
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about scheduled jobs in [this chapter](../../../basics/scheduled-jobs/page.mdx).
|
||||
Learn more about scheduled jobs in [this chapter](../../../fundamentals/scheduled-jobs/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -39,7 +39,7 @@ Workflows have a built-in durable execution engine that helps you complete tasks
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about workflows in [this chapter](../../../basics/workflows/page.mdx).
|
||||
Learn more about workflows in [this chapter](../../../fundamentals/workflows/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -134,7 +134,7 @@ The step passes the created brands to the compensation function, which deletes t
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about compensation functions in [this chapter](../../../advanced-development/workflows/compensation-function/page.mdx).
|
||||
Learn more about compensation functions in [this chapter](../../../fundamentals/workflows/compensation-function/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -220,11 +220,11 @@ export const syncBrandsFromSystemWorkflow = createWorkflow(
|
||||
|
||||
In the workflow, you only use the `retrieveBrandsFromSystemStep` for now, which retrieves the brands from the third-party CMS.
|
||||
|
||||
Next, you need to identify which brands must be created or updated. Since workflows are constructed internally and are only evaluated during execution, you can't access values to perform data manipulation directly. Instead, use [transform](../../../advanced-development/workflows/variable-manipulation/page.mdx) from the Workflows SDK that gives you access to the real-time values of the data, allowing you to create new variables using those values.
|
||||
Next, you need to identify which brands must be created or updated. Since workflows are constructed internally and are only evaluated during execution, you can't access values to perform data manipulation directly. Instead, use [transform](../../../fundamentals/workflows/variable-manipulation/page.mdx) from the Workflows SDK that gives you access to the real-time values of the data, allowing you to create new variables using those values.
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about data manipulation using `transform` in [this chapter](../../../advanced-development/workflows/variable-manipulation/page.mdx).
|
||||
Learn more about data manipulation using `transform` in [this chapter](../../../fundamentals/workflows/variable-manipulation/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -320,7 +320,7 @@ A scheduled job file must export:
|
||||
- `name`: A unique name for the scheduled job.
|
||||
- `schedule`: A string that holds a [cron expression](https://crontab.guru/) indicating the schedule to run the job.
|
||||
|
||||
The scheduled job function accepts as a parameter the [Medusa container](../../../basics/medusa-container/page.mdx) used to resolve framework and commerce tools. You then execute the `syncBrandsFromCmsWorkflow` and use its result to log how many brands were created or updated.
|
||||
The scheduled job function accepts as a parameter the [Medusa container](../../../fundamentals/medusa-container/page.mdx) used to resolve framework and commerce tools. You then execute the `syncBrandsFromCmsWorkflow` and use its result to log how many brands were created or updated.
|
||||
|
||||
Based on the cron expression specified in `config.schedule`, Medusa will run the scheduled job every day at midnight. You can also change it to `* * * * *` to run it every minute for easier debugging.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ In the previous chapters, you've created a [Brand Module](../../custom-features/
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about modules in [this chapter](../../../basics/modules/page.mdx).
|
||||
Learn more about modules in [this chapter](../../../fundamentals/modules/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -66,7 +66,7 @@ export default CmsModuleService
|
||||
|
||||
You create a `CmsModuleService` that will hold the methods to connect to the third-party CMS. A service's constructor accepts two parameters:
|
||||
|
||||
1. The module's container. Since a module is [isolated](../../../advanced-development/modules/isolation/page.mdx), it has a [local container](../../../advanced-development/modules/container/page.mdx) different than the Medusa container you use in other customizations. This container holds framework tools like the [Logger utility](../../../debugging-and-testing/logging/page.mdx) and resources within the module.
|
||||
1. The module's container. Since a module is [isolated](../../../fundamentals/modules/isolation/page.mdx), it has a [local container](../../../fundamentals/modules/container/page.mdx) different than the Medusa container you use in other customizations. This container holds framework tools like the [Logger utility](../../../debugging-and-testing/logging/page.mdx) and resources within the module.
|
||||
2. Options passed to the module when it's later added in Medusa's configurations. These options are useful to pass secret keys or configurations that ensure your module is re-usable across applications. For the CMS Module, you accept the API key to connect to the dummy CMS as an option.
|
||||
|
||||
When integrating a third-party system that has a Node.js SDK or client, you can initialize that client in the constructor to be used in the service's methods.
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Custom Development`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In the next chapters, you’ll customize Medusa using the concepts you learned.
|
||||
|
||||
You'll follow an example of building a Brands Module that leads you through:
|
||||
|
||||
1. The main concepts you need to build custom features.
|
||||
2. How to extend data models that are in the Commerce Modules.
|
||||
3. How to use your custom features in pages and widgets in the admin dashboard.
|
||||
4. How to integrate third-party systems into your Medusa application.
|
||||
@@ -1,67 +0,0 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Your First Customizations`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you’ll build your first customizations with Medusa.
|
||||
|
||||
You'll create a `GET` API route at the path `/hello-world`. An API route exposes your application's commerce features to frontend clients, such as the admin dashboard or a storefront.
|
||||
|
||||
Medusa has [Store](!api!/store) and [Admin](!api!/admin) API routes, and you can create custom API routes for your custom features.
|
||||
|
||||
## 1. Create API Route
|
||||
|
||||
API Routes expose business logic through REST APIs. You can create custom API routes to expose custom business logic.
|
||||
|
||||
To create an API route, create the file `src/api/hello-world/route.ts` with the following content:
|
||||
|
||||
```ts title="src/api/hello-world/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "@medusajs/framework/http"
|
||||
|
||||
export const GET = (
|
||||
req: MedusaRequest,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
res.json({
|
||||
message: "Hello, world!",
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Test Customizations
|
||||
|
||||
To test out your customizations:
|
||||
|
||||
1. Start the Medusa application:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run dev
|
||||
```
|
||||
|
||||
2. Send a `GET` request to `/hello-world`:
|
||||
|
||||
```bash
|
||||
curl http://localhost:9000/hello-world
|
||||
```
|
||||
|
||||
In the response, you’ll receive the following object:
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Hello, world!"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
Congratulations, you’ve made your first customization with Medusa!
|
||||
|
||||
You can now start your in-depth learning journey to become an expert.
|
||||
@@ -130,7 +130,7 @@ The `additional_data` is then passed to hooks in the `createProductsWorkflow` us
|
||||
|
||||
<Note>
|
||||
|
||||
Learn about workflow hooks in [this guide](../../workflows/workflow-hooks/page.mdx).
|
||||
Learn about workflow hooks in [this guide](../../../fundamentals/workflows/workflow-hooks/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -208,7 +208,7 @@ export default defineMiddlewares({
|
||||
The `validateAndTransformQuery` accepts two parameters:
|
||||
|
||||
- The first one is the Zod schema to validate the query parameters against.
|
||||
- The second one is an object of options for retrieving data using Query, which you can learn more about in [this chapter](../../module-links/query/page.mdx).
|
||||
- The second one is an object of options for retrieving data using Query, which you can learn more about in [this chapter](../../../fundamentals/module-links/query/page.mdx).
|
||||
|
||||
#### How the Validation Works
|
||||
|
||||
@@ -4,9 +4,9 @@ export const metadata = {
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In the next chapters, you'll learn more about defining data models.
|
||||
Data models are created and managed in a module. To learn how to create a data model in a custom module, refer to the [Modules chapter](../modules/page.mdx).
|
||||
|
||||
You'll learn about:
|
||||
In the next chapters, you'll learn about defining data models in more details. You'll learn about:
|
||||
|
||||
- The different property types available.
|
||||
- How to set a property as a primary key.
|
||||
@@ -20,7 +20,7 @@ Subscribers are useful to perform actions that aren't integral to the original f
|
||||
|
||||
<Note>
|
||||
|
||||
If the action you're performing is integral to the main flow of the core commerce feature, use [workflow hooks](../../advanced-development/workflows/workflow-hooks/page.mdx) instead.
|
||||
If the action you're performing is integral to the main flow of the core commerce feature, use [workflow hooks](../workflows/workflow-hooks/page.mdx) instead.
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -105,4 +105,4 @@ Medusa provides two Event Modules out of the box:
|
||||
- [Local Event Module](!resources!/architectural-modules/event/local), used by default. It's useful for development, as you don't need additional setup to use it.
|
||||
- [Redis Event Module](!resources!/architectural-modules/event/redis), which is useful in production. It uses [Redis](https://redis.io/) to implement Medusa's pub/sub events system.
|
||||
|
||||
Medusa's [architecture](../../advanced-development/architecture/overview/page.mdx) also allows you to build a custom Event Module that uses a different service or logic to implement the pub/sub system. Learn how to build an Event Module in [this guide](!resources!/architectural-modules/event/create).
|
||||
Medusa's [architecture](../../introduction/architecture/page.mdx) also allows you to build a custom Event Module that uses a different service or logic to implement the pub/sub system. Learn how to build an Event Module in [this guide](!resources!/architectural-modules/event/create).
|
||||
@@ -14,7 +14,7 @@ In other platforms, if you have a resource A (for example, a class) that depends
|
||||
|
||||
Medusa simplifies this process by giving you access to the container, with the tools or resources already registered, at all times in your customizations. When you reach a point in your code where you need a tool, you resolve it from the container and use it.
|
||||
|
||||
For example, consider you're creating an API route that retrieves products based on filters using [Query](../../advanced-development/module-links/query/page.mdx), a tool that fetches data across the application. In the API route's function, you can resolve Query from the container passed to the API route and use it:
|
||||
For example, consider you're creating an API route that retrieves products based on filters using [Query](../../fundamentals/module-links/query/page.mdx), a tool that fetches data across the application. In the API route's function, you can resolve Query from the container passed to the API route and use it:
|
||||
|
||||
export const highlights = [
|
||||
["8", "resolve", "A method that resolves resources from the container."],
|
||||
@@ -53,7 +53,7 @@ The API route accepts as a first parameter a request object that has a `scope` p
|
||||
|
||||
<Note>
|
||||
|
||||
You can learn more about how Query works in [this chapter](../../advanced-development/module-links/query/page.mdx).
|
||||
You can learn more about how Query works in [this chapter](../../fundamentals/module-links/query/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -71,7 +71,7 @@ This section gives quick examples of how to resolve resources from the Medusa co
|
||||
|
||||
### Subscriber
|
||||
|
||||
A [subscriber](../events-and-subscribers/page.mdx) function, which is executed when an event is emitted, accepts as a parameter an object with a `container` property, whose value is the Medusa container. Use its `resolve` method to resolve a resource by its registration key:
|
||||
A [subscriber](../../fundamentals/events-and-subscribers/page.mdx) function, which is executed when an event is emitted, accepts as a parameter an object with a `container` property, whose value is the Medusa container. Use its `resolve` method to resolve a resource by its registration key:
|
||||
|
||||
export const subscriberHighlights = [
|
||||
["6", "container", "Receive the Medusa container as a parameter"],
|
||||
@@ -106,7 +106,7 @@ export const config: SubscriberConfig = {
|
||||
|
||||
### Scheduled Job
|
||||
|
||||
A [scheduled job](../scheduled-jobs/page.mdx) function, which is executed at a specified interval, accepts the Medusa container as a parameter. Use its `resolve` method to resolve a resource by its registration key:
|
||||
A [scheduled job](../../fundamentals/scheduled-jobs/page.mdx) function, which is executed at a specified interval, accepts the Medusa container as a parameter. Use its `resolve` method to resolve a resource by its registration key:
|
||||
|
||||
export const scheduledJobHighlights = [
|
||||
["5", "container", "Receive the Medusa container as a parameter"],
|
||||
@@ -144,7 +144,7 @@ export const config = {
|
||||
|
||||
### Workflow Step
|
||||
|
||||
A [step in a workflow](../workflows/page.mdx), which is a special function where you build durable execution logic across multiple modules, accepts in its second parameter a `container` property, whose value is the Medusa container. Use its `resolve` method to resolve a resource by its registration key:
|
||||
A [step in a workflow](../../fundamentals/workflows/page.mdx), which is a special function where you build durable execution logic across multiple modules, accepts in its second parameter a `container` property, whose value is the Medusa container. Use its `resolve` method to resolve a resource by its registration key:
|
||||
|
||||
export const workflowStepsHighlight = [
|
||||
["7", "container", "Receive the Medusa container as a parameter"],
|
||||
@@ -175,6 +175,6 @@ const step1 = createStep("step-1", async (_, { container }) => {
|
||||
|
||||
### Module Services and Loaders
|
||||
|
||||
A [module](../modules/page.mdx), which is a package of functionalities for a single feature or domain, has its own container, so it can't resolve resources from the Medusa container.
|
||||
A [module](../../fundamentals/modules/page.mdx), which is a package of functionalities for a single feature or domain, has its own container, so it can't resolve resources from the Medusa container.
|
||||
|
||||
Learn more about the module's container in [this chapter](../../advanced-development/modules/container/page.mdx).
|
||||
Learn more about the module's container in [this chapter](../../fundamentals/modules/container/page.mdx).
|
||||
@@ -288,7 +288,7 @@ The `order` property is an object whose keys are property names, and values are
|
||||
|
||||
For API routes that retrieve a single or list of resources, Medusa provides a `validateAndTransformQuery` middleware that:
|
||||
|
||||
- Validates accepted query parameters, as explained in [this documentation](../../api-routes/validation/page.mdx).
|
||||
- Validates accepted query parameters, as explained in [this documentation](../../../fundamentals/api-routes/validation/page.mdx).
|
||||
- Parses configurations that are received as query parameters to be passed to Query.
|
||||
|
||||
Using this middleware allows you to have default configurations for retrieved fields and relations or pagination, while allowing clients to customize them per request.
|
||||
@@ -331,7 +331,7 @@ export default defineMiddlewares({
|
||||
|
||||
The `validateAndTransformQuery` accepts two parameters:
|
||||
|
||||
1. A Zod validation schema for the query parameters, which you can learn more about in the [API Route Validation documentation](../../api-routes/validation/page.mdx). Medusa has a `createFindParams` utility that generates a Zod schema that accepts four query parameters:
|
||||
1. A Zod validation schema for the query parameters, which you can learn more about in the [API Route Validation documentation](../../../fundamentals/api-routes/validation/page.mdx). Medusa has a `createFindParams` utility that generates a Zod schema that accepts four query parameters:
|
||||
1. `fields`: The fields and relations to retrieve in the returned resources.
|
||||
2. `offset`: The number of items to skip before retrieving the returned items.
|
||||
3. `limit`: The maximum number of items to return.
|
||||
@@ -8,7 +8,7 @@ In this chapter, you'll learn about Medusa's commerce modules.
|
||||
|
||||
## What is a Commerce Module?
|
||||
|
||||
Commerce modules are built-in [modules](../modules/page.mdx) of Medusa that provide core commerce logic specific to domains like Products, Orders, Customers, Fulfillment, and much more.
|
||||
Commerce modules are built-in [modules](../page.mdx) of Medusa that provide core commerce logic specific to domains like Products, Orders, Customers, Fulfillment, and much more.
|
||||
|
||||
Medusa's commerce modules are used to form Medusa's default [workflows](!resources!/medusa-workflows-reference) and [APIs](!api!/store). For example, when you call the add to cart endpoint. the add to cart workflow runs which uses the Product Module to check if the product exists, the Inventory Module to ensure the product is available in the inventory, and the Cart Module to finally add the product to the cart.
|
||||
|
||||
@@ -28,9 +28,9 @@ Refer to [this reference](!resources!/commerce-modules) for a full list of comme
|
||||
|
||||
## Use Commerce Modules in Custom Flows
|
||||
|
||||
Similar to your [custom modules](../modules/page.mdx), the Medusa application registers a commerce module's service in the [container](../medusa-container/page.mdx). So, you can resolve it in your custom flows. This is useful as you build unique requirements extending core commerce features.
|
||||
Similar to your [custom modules](../page.mdx), the Medusa application registers a commerce module's service in the [container](../../medusa-container/page.mdx). So, you can resolve it in your custom flows. This is useful as you build unique requirements extending core commerce features.
|
||||
|
||||
For example, consider you have a [workflow](../workflows/page.mdx) (a special function that performs a task in a series of steps with rollback mechanism) that needs a step to retrieve the total number of products. You can create a step in the workflow that resolves the Product Module's service from the container to use its methods:
|
||||
For example, consider you have a [workflow](../../../fundamentals/workflows/page.mdx) (a special function that performs a task in a series of steps with rollback mechanism) that needs a step to retrieve the total number of products. You can create a step in the workflow that resolves the Product Module's service from the container to use its methods:
|
||||
|
||||
export const highlights = [
|
||||
["6", `"product"`, "Resolve the Product Module's service from the container."],
|
||||
@@ -9,7 +9,7 @@ In this chapter, you'll learn how modules are isolated, and what that means for
|
||||
<Note title="Summary">
|
||||
|
||||
- Modules can't access resources, such as services or data models, from other modules.
|
||||
- Use Medusa's linking concepts, as explained in the [Module Links chapters](../../module-links/page.mdx), to extend a module's data models and retrieve data across modules.
|
||||
- Use Medusa's linking concepts, as explained in the [Module Links chapters](../../../fundamentals/module-links/page.mdx), to extend a module's data models and retrieve data across modules.
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -33,7 +33,7 @@ Some of the module isolation's benefits include:
|
||||
|
||||
## How to Extend Data Model of Another Module?
|
||||
|
||||
To extend the data model of another module, such as the `product` data model of the Product Module, use Medusa's linking concepts as explained in the [Module Links chapters](../../module-links/page.mdx).
|
||||
To extend the data model of another module, such as the `product` data model of the Product Module, use Medusa's linking concepts as explained in the [Module Links chapters](../../../fundamentals/module-links/page.mdx).
|
||||
|
||||
---
|
||||
|
||||
@@ -12,13 +12,13 @@ In this chapter, you’ll learn about loaders and how to use them.
|
||||
|
||||
When building a commerce application, you'll often need to execute an action the first time the application starts. For example, if your application needs to connect to databases other than Medusa's PostgreSQL database, you might need to establish a connection on application startup.
|
||||
|
||||
In Medusa, you can execute an action when the application starts using a loader. A loader is a function exported by a [module](../modules/page.mdx), which is a package of business logic for a single domain. When the Medusa application starts, it executes all loaders exported by configured modules.
|
||||
In Medusa, you can execute an action when the application starts using a loader. A loader is a function exported by a [module](../page.mdx), which is a package of business logic for a single domain. When the Medusa application starts, it executes all loaders exported by configured modules.
|
||||
|
||||
Loaders are useful to register custom resources, such as database connections, in the [module's container](../../advanced-development/modules/container/page.mdx), which is similar to the [Medusa container](../medusa-container/page.mdx) but includes only [resources available to the module](!resources!/medusa-container-resources#module-container-resources). Modules are isolated, so they can't access resources outside of them, such as a service in another module.
|
||||
Loaders are useful to register custom resources, such as database connections, in the [module's container](../container/page.mdx), which is similar to the [Medusa container](../../medusa-container/page.mdx) but includes only [resources available to the module](!resources!/medusa-container-resources#module-container-resources). Modules are isolated, so they can't access resources outside of them, such as a service in another module.
|
||||
|
||||
<Note title="Why are modules isolated?">
|
||||
|
||||
Medusa isolates modules to ensure that they're re-usable across applications, aren't tightly coupled to other resources, and don't have implications when integrated into the Medusa application. Learn more about why modules are isolated in [this chapter](../../advanced-development/modules/isolation/page.mdx), and check out [this reference for the list of resources in the module's container](!resources!/medusa-container-resources#module-container-resources).
|
||||
Medusa isolates modules to ensure that they're re-usable across applications, aren't tightly coupled to other resources, and don't have implications when integrated into the Medusa application. Learn more about why modules are isolated in [this chapter](../isolation/page.mdx), and check out [this reference for the list of resources in the module's container](!resources!/medusa-container-resources#module-container-resources).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -36,7 +36,7 @@ For example, consider you have a `hello` module, you can create a loader at `src
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Learn how to create a module in [this chapter](../modules/page.mdx).
|
||||
Learn how to create a module in [this chapter](../page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -84,7 +84,7 @@ The second parameter of the `Module` function accepts a `loaders` property whose
|
||||
|
||||
### Test the Loader
|
||||
|
||||
Assuming your module is [added to Medusa's configuration](../modules/page.mdx#4-add-module-to-medusas-configurations), you can test the loader by starting the Medusa application:
|
||||
Assuming your module is [added to Medusa's configuration](../page.mdx#4-add-module-to-medusas-configurations), you can test the loader by starting the Medusa application:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run dev
|
||||
@@ -10,13 +10,13 @@ In this document, you'll learn about the expected files and directories in your
|
||||
|
||||
## index.ts
|
||||
|
||||
The `index.ts` file in the root of your module's directory is the only required file. It must export the module's definition as explained in a [previous chapter](../modules/page.mdx).
|
||||
The `index.ts` file in the root of your module's directory is the only required file. It must export the module's definition as explained in a [previous chapter](../page.mdx).
|
||||
|
||||
---
|
||||
|
||||
## service.ts
|
||||
|
||||
A module must have a main service. It's created in the `service.ts` file at the root of your module directory as explained in a [previous chapter](../modules/page.mdx).
|
||||
A module must have a main service. It's created in the `service.ts` file at the root of your module directory as explained in a [previous chapter](../page.mdx).
|
||||
|
||||
---
|
||||
|
||||
@@ -20,7 +20,7 @@ As you learn more about Medusa, you will see that modules are central to customi
|
||||
|
||||
## How to Create a Module?
|
||||
|
||||
In a module, you define data models that represent new tables in the database, and you manage these models in a class called a service. Then, the Medusa application registers the module's service in the [Medusa container](../medusa-container/page.mdx) so that you can build commerce flows and features around the functionalities provided by the module.
|
||||
In a module, you define data models that represent new tables in the database, and you manage these models in a class called a service. Then, the Medusa application registers the module's service in the [Medusa container](../../fundamentals/medusa-container/page.mdx) so that you can build commerce flows and features around the functionalities provided by the module.
|
||||
|
||||
In this section, you'll build a Blog Module that has a `Post` data model and a service to manage that data model, you'll expose an API endpoint to create a blog post.
|
||||
|
||||
@@ -53,7 +53,7 @@ You define the data model using the `define` method of the `model` utility impor
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Learn about other property types in [this chapter](../../advanced-development/data-models/property-types/page.mdx).
|
||||
Learn about other property types in [this chapter](../../fundamentals/data-models/property-types/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -61,7 +61,7 @@ The code snippet above defines a `Post` data model with `id` and `title` propert
|
||||
|
||||
### 2. Create Service
|
||||
|
||||
You perform database operations on your data models in a service, which is a class exported by the module and acts like an interface to its functionalities. Medusa registers the service in its [container](../medusa-container/page.mdx), allowing you to resolve and use it when building custom commerce flows.
|
||||
You perform database operations on your data models in a service, which is a class exported by the module and acts like an interface to its functionalities. Medusa registers the service in its [container](../../fundamentals/medusa-container/page.mdx), allowing you to resolve and use it when building custom commerce flows.
|
||||
|
||||
You define a service in a `service.ts` or `service.js` file at the root of your module's directory. So, to create the Blog Module's service, create the file `src/modules/blog/service.ts` with the following content:
|
||||
|
||||
@@ -205,11 +205,11 @@ This creates the `post` table in the database.
|
||||
|
||||
Since the module's main service is registered in the Medusa container, you can resolve it in other customizations to use its methods.
|
||||
|
||||
To test out the Blog Module, you'll add the functionality to create a post in a [workflow](../workflows/page.mdx), which is a special function that performs a task in a series of steps with rollback logic. Then, you'll expose an [API route](../api-routes/page.mdx) that creates a blog post by executing the workflow.
|
||||
To test out the Blog Module, you'll add the functionality to create a post in a [workflow](../../fundamentals/workflows/page.mdx), which is a special function that performs a task in a series of steps with rollback logic. Then, you'll expose an [API route](../api-routes/page.mdx) that creates a blog post by executing the workflow.
|
||||
|
||||
<Note title="Why use a workflow?">
|
||||
|
||||
By building a commerce feature in a workflow, you can execute it in other customizations while ensuring data consistency across systems. If an error occurs during execution, every step has its own rollback logic to undo its actions. Workflows have other special features which you can learn about in [this chapter](../workflows/page.mdx).
|
||||
By building a commerce feature in a workflow, you can execute it in other customizations while ensuring data consistency across systems. If an error occurs during execution, every step has its own rollback logic to undo its actions. Workflows have other special features which you can learn about in [this chapter](../../fundamentals/workflows/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -326,4 +326,4 @@ This will create a post and return it in the response:
|
||||
}
|
||||
```
|
||||
|
||||
You can also execute the workflow from a [subscriber](../events-and-subscribers/page.mdx) when an event occurs, or from a [scheduled job](../scheduled-jobs/page.mdx) to run it at a specified interval.
|
||||
You can also execute the workflow from a [subscriber](../../fundamentals/events-and-subscribers/page.mdx) when an event occurs, or from a [scheduled job](../../fundamentals/scheduled-jobs/page.mdx) to run it at a specified interval.
|
||||
@@ -17,7 +17,7 @@ Medusa removes this overhead by supporting this feature natively with scheduled
|
||||
<Note title="Don't use scheduled jobs if" type="error">
|
||||
|
||||
- You want the action to execute at a specified schedule while the Medusa application **isn't** running. Instead, use the operating system's equivalent of a cron job.
|
||||
- You want to execute the action once when the application loads. Use [loaders](../loaders/page.mdx) instead.
|
||||
- You want to execute the action once when the application loads. Use [loaders](../modules/loaders/page.mdx) instead.
|
||||
- You want to execute the action if an event occurs. Use [subscribers](../events-and-subscribers/page.mdx) instead.
|
||||
|
||||
</Note>
|
||||
@@ -22,7 +22,7 @@ However, unlike regular functions, workflows:
|
||||
- Support defining roll-back logic for each step, so that you can handle errors gracefully and your data remain consistent across systems.
|
||||
- Perform long actions asynchronously, giving you control over when a step starts and finishes.
|
||||
|
||||
You implement all custom flows within workflows, then execute them from [API routes](../api-routes/page.mdx), [subscribers](../events-and-subscribers/page.mdx), and [scheduled jobs](../scheduled-jobs/page.mdx).
|
||||
You implement all custom flows within workflows, then execute them from [API routes](../api-routes/page.mdx), [subscribers](../../fundamentals/events-and-subscribers/page.mdx), and [scheduled jobs](../../fundamentals/scheduled-jobs/page.mdx).
|
||||
|
||||
---
|
||||
|
||||
@@ -103,6 +103,32 @@ Replace `admin@medusajs.com` and `supersecret` with the user's email and passwor
|
||||
|
||||
You can then use the user's credentials to log into the Medusa Admin application.
|
||||
|
||||
---
|
||||
|
||||
## Project Files
|
||||
|
||||
Your Medusa application's project will have the following files and directories:
|
||||
|
||||

|
||||
|
||||
### src
|
||||
|
||||
This directory is the central place for your custom development. It includes the following sub-directories:
|
||||
|
||||
- `admin`: Holds your admin dashboard's custom [widgets](../fundamentals/admin/widgets/page.mdx) and [UI routes](../fundamentals/admin/ui-routes/page.mdx).
|
||||
- `api`: Holds your custom [API routes](../fundamentals/api-routes/page.mdx) that are added as endpoints in your Medusa application.
|
||||
- `jobs`: Holds your [scheduled jobs](../fundamentals/scheduled-jobs/page.mdx) that run at a specified interval during your Medusa application's runtime.
|
||||
- `links`: Holds you [module links](../fundamentals/module-links/page.mdx) that build associations between data models of different modules.
|
||||
- `modules`: Holds your custom [modules](../fundamentals/modules/page.mdx) that implement custom business logic.
|
||||
- `scripts`: Holds your custom [scripts](../fundamentals/custom-cli-scripts/page.mdx) to be executed using Medusa's CLI tool.
|
||||
- `subscribers`: Holds your [event listeners](../fundamentals/events-and-subscribers/page.mdx) that are executed asynchronously whenever an event is emitted.
|
||||
- `workflows`: Holds your custom [flows](../fundamentals/workflows/page.mdx) that can be executed from anywhere in your application.
|
||||
|
||||
### medusa-config.ts
|
||||
|
||||
This file holds your [Medusa configurations](!resources!/references/medusa-config), such as your PostgreSQL database configurations.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Configure Medusa Application
|
||||
@@ -115,4 +141,4 @@ If you run into issues with configurations, such as CORS configurations, or need
|
||||
|
||||
## Next Steps
|
||||
|
||||
In the next documentation pages, you'll start customizing your Medusa application, learn about the project's directory structure, and learn about different basic concepts.
|
||||
In the next chapters, you'll learn about the architecture of your Medusa application, then learn how to customize your application to build custom features.
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
import { Table } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Cheat sheet`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
This chapter provides a cheat sheet for Medusa's resources on when to use or not use them.
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Name</Table.HeaderCell>
|
||||
<Table.HeaderCell>Use if</Table.HeaderCell>
|
||||
<Table.HeaderCell>Don't use if</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body className="[&_td]:align-top [&_td]:pt-1 [&_td:first-child]:font-bold">
|
||||
<Table.Row>
|
||||
<Table.Cell>API Routes</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You're exposing custom functionality to be used in the admin dashboard or an external application, such as a storefront.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Modules</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You're implementing a custom commerce feature. For example, you're implementing digital products.
|
||||
- You want to extend data models in other commerce modules, such as adding a field or a relation to the Product model.
|
||||
- You want to re-use your custom commerce functionalities across Medusa applications or use them in other environments, such as Edge functions and Next.js apps.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Module Links</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want to create a relation between data models from different modules.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want to create a relationship between data models in the same module. Use data model relationships instead.
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Data Models</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want to store data related to your customization in the database.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want to store simple key-value pairs related to a Medusa data model. Instead, use the `metadata` field that models have, which is an object of custom key-value pairs.
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Data Model Relationships</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want to create a relation between data models in the same module.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want to create a relationship between data models in different modules. Use module links instead.
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Loaders</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You're performing an action at application start-up.
|
||||
- You're establishing a one-time connection with an external system.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want to perform an action continuously or at a set time pattern in the application. Use scheduled jobs instead.
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Subscribers</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want to perform an action everytime a specific event is emitted in the Medusa application.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Scheduled Jobs</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You're executing an action at a specified time interval during application runtime.
|
||||
- The action must be executed automatically.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want the action to execute at a specified time interval while the Medusa application **isn't** running. Instead, use the operating system's equivalent of a cron job.
|
||||
- You want to execute the action once. Use loaders instead.
|
||||
- You want to execute the action if an event occurs. Use subscribers instead.
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Workflows</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You're defining a flow with interactions across multiple systems and services.
|
||||
- You're defining flows to be used across different resources. For example, if you want to invoke the flow manually through an API Router, but also want to automate its running through a scheduled job.
|
||||
- You want to define how the series of actions are rolled-back when an error occurs.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>Middlewares</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
- You want to protect API routes by a custom condition.
|
||||
- You're modifying the request body.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
@@ -24,7 +24,7 @@ const HomepageCodeTabs = () => {
|
||||
"Expose custom features with REST API routes, then consume them from your client applications.",
|
||||
link: {
|
||||
title: "API Routes",
|
||||
link: "/learn/basics/api-routes",
|
||||
link: "/learn/fundamentals/api-routes",
|
||||
},
|
||||
},
|
||||
code: {
|
||||
@@ -64,7 +64,7 @@ const HomepageCodeTabs = () => {
|
||||
"Build flows as a series of steps, with retry mechanisms and tracking of each steps' status.",
|
||||
link: {
|
||||
title: "Workflows",
|
||||
link: "/learn/basics/workflows",
|
||||
link: "/learn/fundamentals/workflows",
|
||||
},
|
||||
},
|
||||
code: {
|
||||
@@ -105,7 +105,7 @@ const HomepageCodeTabs = () => {
|
||||
"Create data models that represent tables in the database using Medusa's Data Model Language.",
|
||||
link: {
|
||||
title: "DML",
|
||||
link: "/learn/basics/modules#1-create-data-model",
|
||||
link: "/learn/fundamentals/modules#1-create-data-model",
|
||||
},
|
||||
},
|
||||
code: {
|
||||
@@ -141,7 +141,7 @@ const HomepageCodeTabs = () => {
|
||||
"Build custom modules with commerce or architectural features and use them in API routes or workflows.",
|
||||
link: {
|
||||
title: "Modules",
|
||||
link: "/learn/basics/modules",
|
||||
link: "/learn/fundamentals/modules",
|
||||
},
|
||||
},
|
||||
code: {
|
||||
@@ -193,7 +193,7 @@ export async function POST(
|
||||
"Add custom properties to Medusa's data models using module links to build custom use cases.",
|
||||
link: {
|
||||
title: "Module Links",
|
||||
link: "/learn/advanced-development/module-links",
|
||||
link: "/learn/fundamentals/module-links",
|
||||
},
|
||||
},
|
||||
code: {
|
||||
@@ -223,7 +223,7 @@ export default defineLink(
|
||||
"Handle events emitted by the Medusa application to perform custom actions.",
|
||||
link: {
|
||||
title: "Subscribers",
|
||||
link: "/learn/basics/events-and-subscribers",
|
||||
link: "/learn/fundamentals/events-and-subscribers",
|
||||
},
|
||||
},
|
||||
code: {
|
||||
@@ -271,8 +271,8 @@ export const config: SubscriberConfig = {
|
||||
content:
|
||||
"Inject widgets into predefined zones in the Medusa Admin, or add new pages.",
|
||||
link: {
|
||||
title: "Admin Customizations",
|
||||
link: "/learn/basics/admin-customizations",
|
||||
title: "Admin Widgets",
|
||||
link: "/learn/fundamentals/admin/widgets",
|
||||
},
|
||||
},
|
||||
code: {
|
||||
|
||||
@@ -24,11 +24,11 @@ const HomepageLinksSection = () => {
|
||||
title: "Admin Development",
|
||||
links: [
|
||||
{
|
||||
href: "/learn/basics/admin-customizations",
|
||||
href: "/learn/fundamentals/admin/widgets",
|
||||
text: "Build a UI Widget",
|
||||
},
|
||||
{
|
||||
href: "/learn/advanced-development/admin/ui-routes",
|
||||
href: "/learn/fundamentals/admin/ui-routes",
|
||||
text: "Add a UI Route",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,121 +1,112 @@
|
||||
export const generatedEditDates = {
|
||||
"app/learn/basics/scheduled-jobs/page.mdx": "2024-11-29T07:47:23.809Z",
|
||||
"app/learn/basics/workflows/page.mdx": "2024-11-29T08:00:47.637Z",
|
||||
"app/learn/fundamentals/scheduled-jobs/page.mdx": "2024-12-09T10:51:40.570Z",
|
||||
"app/learn/fundamentals/workflows/page.mdx": "2024-12-09T10:52:19.379Z",
|
||||
"app/learn/deployment/page.mdx": "2024-11-25T14:32:44.949Z",
|
||||
"app/learn/page.mdx": "2024-11-28T14:17:53.023Z",
|
||||
"app/learn/basics/commerce-modules/page.mdx": "2024-11-28T15:50:01.284Z",
|
||||
"app/learn/advanced-development/workflows/retry-failed-steps/page.mdx": "2024-09-30T08:43:53.130Z",
|
||||
"app/learn/advanced-development/workflows/workflow-hooks/page.mdx": "2024-09-30T08:43:53.131Z",
|
||||
"app/learn/cheatsheet/page.mdx": "2024-07-11T13:53:40+03:00",
|
||||
"app/learn/fundamentals/modules/commerce-modules/page.mdx": "2024-12-09T10:46:29.339Z",
|
||||
"app/learn/fundamentals/workflows/retry-failed-steps/page.mdx": "2024-12-04T07:37:59.823Z",
|
||||
"app/learn/fundamentals/workflows/workflow-hooks/page.mdx": "2024-12-09T10:44:33.781Z",
|
||||
"app/learn/debugging-and-testing/logging/page.mdx": "2024-09-30T08:43:53.135Z",
|
||||
"app/learn/more-resources/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/learn/storefront-development/page.mdx": "2024-09-11T10:58:59.290Z",
|
||||
"app/learn/storefront-development/nextjs-starter/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/learn/basics/page.mdx": "2024-09-03T07:11:06.879Z",
|
||||
"app/learn/basics/admin-customizations/page.mdx": "2024-10-07T12:41:39.218Z",
|
||||
"app/learn/advanced-development/workflows/workflow-timeout/page.mdx": "2024-09-30T08:43:53.131Z",
|
||||
"app/learn/advanced-development/workflows/parallel-steps/page.mdx": "2024-09-30T08:43:53.130Z",
|
||||
"app/learn/advanced-development/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/learn/first-customizations/page.mdx": "2024-09-11T10:48:42.374Z",
|
||||
"app/learn/fundamentals/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/learn/fundamentals/admin-customizations/page.mdx": "2024-10-07T12:41:39.218Z",
|
||||
"app/learn/fundamentals/workflows/workflow-timeout/page.mdx": "2024-10-21T13:30:21.372Z",
|
||||
"app/learn/fundamentals/workflows/parallel-steps/page.mdx": "2024-10-21T13:30:21.372Z",
|
||||
"app/learn/debugging-and-testing/page.mdx": "2024-05-03T17:36:38+03:00",
|
||||
"app/learn/basics/medusa-container/page.mdx": "2024-11-28T14:28:30.248Z",
|
||||
"app/learn/basics/project-directories-files/page.mdx": "2024-11-28T14:27:01.290Z",
|
||||
"app/learn/basics/api-routes/page.mdx": "2024-11-28T15:44:30.413Z",
|
||||
"app/learn/basics/modules-directory-structure/page.mdx": "2024-10-03T13:03:35.957Z",
|
||||
"app/learn/advanced-development/workflows/access-workflow-errors/page.mdx": "2024-09-18T12:54:04.695Z",
|
||||
"app/learn/basics/events-and-subscribers/page.mdx": "2024-11-29T07:44:23.499Z",
|
||||
"app/learn/advanced-development/modules/container/page.mdx": "2024-11-21T08:59:18.707Z",
|
||||
"app/learn/advanced-development/workflows/execute-another-workflow/page.mdx": "2024-09-30T08:43:53.129Z",
|
||||
"app/learn/basics/loaders/page.mdx": "2024-11-29T07:36:00.800Z",
|
||||
"app/learn/advanced-development/admin/widgets/page.mdx": "2024-11-29T07:59:37.919Z",
|
||||
"app/learn/advanced-development/data-models/page.mdx": "2024-09-19T07:26:43.535Z",
|
||||
"app/learn/advanced-development/modules/remote-link/page.mdx": "2024-09-30T08:43:53.127Z",
|
||||
"app/learn/advanced-development/api-routes/protected-routes/page.mdx": "2024-09-30T08:43:53.121Z",
|
||||
"app/learn/advanced-development/workflows/add-workflow-hook/page.mdx": "2024-09-30T08:43:53.128Z",
|
||||
"app/learn/advanced-development/events-and-subscribers/data-payload/page.mdx": "2024-07-16T17:12:05+01:00",
|
||||
"app/learn/advanced-development/data-models/default-properties/page.mdx": "2024-09-19T07:32:06.118Z",
|
||||
"app/learn/advanced-development/workflows/advanced-example/page.mdx": "2024-09-11T10:46:59.975Z",
|
||||
"app/learn/advanced-development/events-and-subscribers/emit-event/page.mdx": "2024-11-11T15:17:58.045Z",
|
||||
"app/learn/advanced-development/workflows/conditions/page.mdx": "2024-09-30T08:43:53.128Z",
|
||||
"app/learn/advanced-development/modules/module-link-directions/page.mdx": "2024-07-24T09:16:01+02:00",
|
||||
"app/learn/advanced-development/admin/page.mdx": "2024-10-07T12:39:13.178Z",
|
||||
"app/learn/advanced-development/workflows/long-running-workflow/page.mdx": "2024-09-30T08:43:53.129Z",
|
||||
"app/learn/advanced-development/workflows/constructor-constraints/page.mdx": "2024-11-14T16:13:19.234Z",
|
||||
"app/learn/advanced-development/data-models/write-migration/page.mdx": "2024-07-15T17:46:10+02:00",
|
||||
"app/learn/advanced-development/data-models/manage-relationships/page.mdx": "2024-09-10T11:39:51.167Z",
|
||||
"app/learn/advanced-development/modules/remote-query/page.mdx": "2024-07-21T21:20:24+02:00",
|
||||
"app/learn/advanced-development/modules/options/page.mdx": "2024-10-16T08:49:27.162Z",
|
||||
"app/learn/advanced-development/data-models/relationships/page.mdx": "2024-12-04T10:52:32.992Z",
|
||||
"app/learn/advanced-development/workflows/compensation-function/page.mdx": "2024-11-28T14:05:29.691Z",
|
||||
"app/learn/advanced-development/modules/service-factory/page.mdx": "2024-09-30T08:43:53.127Z",
|
||||
"app/learn/advanced-development/data-models/primary-key/page.mdx": "2024-09-30T08:43:53.123Z",
|
||||
"app/learn/advanced-development/modules/module-links/page.mdx": "2024-09-30T08:43:53.126Z",
|
||||
"app/learn/advanced-development/data-models/searchable-property/page.mdx": "2024-09-30T08:43:53.125Z",
|
||||
"app/learn/advanced-development/scheduled-jobs/execution-number/page.mdx": "2024-07-02T09:41:15+00:00",
|
||||
"app/learn/advanced-development/api-routes/parameters/page.mdx": "2024-11-12T13:35:09.393Z",
|
||||
"app/learn/advanced-development/api-routes/http-methods/page.mdx": "2024-09-11T10:43:33.169Z",
|
||||
"app/learn/advanced-development/admin/tips/page.mdx": "2024-10-07T12:50:36.335Z",
|
||||
"app/learn/advanced-development/api-routes/cors/page.mdx": "2024-09-30T08:43:53.121Z",
|
||||
"app/learn/advanced-development/admin/ui-routes/page.mdx": "2024-11-29T08:10:52.377Z",
|
||||
"app/learn/advanced-development/api-routes/middlewares/page.mdx": "2024-09-11T10:45:31.861Z",
|
||||
"app/learn/advanced-development/modules/isolation/page.mdx": "2024-07-04T17:26:03+03:00",
|
||||
"app/learn/advanced-development/data-models/configure-properties/page.mdx": "2024-09-30T08:43:53.122Z",
|
||||
"app/learn/advanced-development/data-models/index/page.mdx": "2024-09-30T08:43:53.122Z",
|
||||
"app/learn/advanced-development/custom-cli-scripts/page.mdx": "2024-09-30T08:43:53.122Z",
|
||||
"app/learn/advanced-development/data-models/property-types/page.mdx": "2024-09-30T08:43:53.124Z",
|
||||
"app/learn/fundamentals/medusa-container/page.mdx": "2024-12-09T11:02:38.225Z",
|
||||
"app/learn/fundamentals/api-routes/page.mdx": "2024-12-04T11:02:57.134Z",
|
||||
"app/learn/fundamentals/modules/modules-directory-structure/page.mdx": "2024-12-09T10:32:46.839Z",
|
||||
"app/learn/fundamentals/workflows/access-workflow-errors/page.mdx": "2024-10-21T13:30:21.371Z",
|
||||
"app/learn/fundamentals/events-and-subscribers/page.mdx": "2024-12-09T10:48:09.285Z",
|
||||
"app/learn/fundamentals/modules/container/page.mdx": "2024-11-21T09:22:27.898Z",
|
||||
"app/learn/fundamentals/workflows/execute-another-workflow/page.mdx": "2024-10-23T07:08:55.900Z",
|
||||
"app/learn/fundamentals/modules/loaders/page.mdx": "2024-12-09T10:32:29.221Z",
|
||||
"app/learn/fundamentals/admin/widgets/page.mdx": "2024-12-04T11:02:57.133Z",
|
||||
"app/learn/fundamentals/data-models/page.mdx": "2024-12-09T11:34:51.065Z",
|
||||
"app/learn/fundamentals/modules/remote-link/page.mdx": "2024-09-30T08:43:53.127Z",
|
||||
"app/learn/fundamentals/api-routes/protected-routes/page.mdx": "2024-11-13T10:44:04.225Z",
|
||||
"app/learn/fundamentals/workflows/add-workflow-hook/page.mdx": "2024-10-21T13:30:21.371Z",
|
||||
"app/learn/fundamentals/events-and-subscribers/data-payload/page.mdx": "2024-10-21T13:30:21.369Z",
|
||||
"app/learn/fundamentals/data-models/default-properties/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/workflows/advanced-example/page.mdx": "2024-09-11T10:46:59.975Z",
|
||||
"app/learn/fundamentals/events-and-subscribers/emit-event/page.mdx": "2024-11-25T16:19:32.168Z",
|
||||
"app/learn/fundamentals/workflows/conditions/page.mdx": "2024-10-21T13:30:21.371Z",
|
||||
"app/learn/fundamentals/modules/module-link-directions/page.mdx": "2024-07-24T09:16:01+02:00",
|
||||
"app/learn/fundamentals/admin/page.mdx": "2024-10-23T07:08:55.898Z",
|
||||
"app/learn/fundamentals/workflows/long-running-workflow/page.mdx": "2024-12-04T07:37:59.822Z",
|
||||
"app/learn/fundamentals/workflows/constructor-constraints/page.mdx": "2024-11-25T16:19:32.168Z",
|
||||
"app/learn/fundamentals/data-models/write-migration/page.mdx": "2024-11-11T15:27:59.794Z",
|
||||
"app/learn/fundamentals/data-models/manage-relationships/page.mdx": "2024-10-28T04:22:21.328Z",
|
||||
"app/learn/fundamentals/modules/remote-query/page.mdx": "2024-07-21T21:20:24+02:00",
|
||||
"app/learn/fundamentals/modules/options/page.mdx": "2024-11-19T16:37:47.253Z",
|
||||
"app/learn/fundamentals/data-models/relationships/page.mdx": "2024-12-06T14:34:50.384Z",
|
||||
"app/learn/fundamentals/workflows/compensation-function/page.mdx": "2024-12-06T14:34:50.384Z",
|
||||
"app/learn/fundamentals/modules/service-factory/page.mdx": "2024-10-21T13:30:21.371Z",
|
||||
"app/learn/fundamentals/data-models/primary-key/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/modules/module-links/page.mdx": "2024-09-30T08:43:53.126Z",
|
||||
"app/learn/fundamentals/data-models/searchable-property/page.mdx": "2024-10-21T13:30:21.369Z",
|
||||
"app/learn/fundamentals/scheduled-jobs/execution-number/page.mdx": "2024-10-21T13:30:21.371Z",
|
||||
"app/learn/fundamentals/api-routes/parameters/page.mdx": "2024-11-19T16:37:47.251Z",
|
||||
"app/learn/fundamentals/api-routes/http-methods/page.mdx": "2024-10-21T13:30:21.367Z",
|
||||
"app/learn/fundamentals/admin/tips/page.mdx": "2024-11-19T16:43:01.662Z",
|
||||
"app/learn/fundamentals/api-routes/cors/page.mdx": "2024-10-21T13:30:21.366Z",
|
||||
"app/learn/fundamentals/admin/ui-routes/page.mdx": "2024-12-04T11:02:57.133Z",
|
||||
"app/learn/fundamentals/api-routes/middlewares/page.mdx": "2024-10-21T13:30:21.367Z",
|
||||
"app/learn/fundamentals/modules/isolation/page.mdx": "2024-12-09T11:02:38.087Z",
|
||||
"app/learn/fundamentals/data-models/configure-properties/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/data-models/index/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/custom-cli-scripts/page.mdx": "2024-10-23T07:08:55.898Z",
|
||||
"app/learn/fundamentals/data-models/property-types/page.mdx": "2024-10-28T04:22:27.540Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2024-09-30T08:43:53.136Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/integration-tests/page.mdx": "2024-09-10T11:39:51.170Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2024-09-30T08:43:53.139Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/page.mdx": "2024-09-30T08:43:53.139Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/unit-tests/module-example/page.mdx": "2024-09-02T11:04:27.232Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/unit-tests/page.mdx": "2024-09-02T11:03:26.997Z",
|
||||
"app/learn/advanced-development/modules/service-constraints/page.mdx": "2024-09-30T08:43:53.127Z",
|
||||
"app/learn/advanced-development/api-routes/page.mdx": "2024-09-04T09:36:33.961Z",
|
||||
"app/learn/advanced-development/api-routes/responses/page.mdx": "2024-09-11T10:44:37.016Z",
|
||||
"app/learn/advanced-development/api-routes/validation/page.mdx": "2024-11-12T13:32:32.484Z",
|
||||
"app/learn/advanced-development/api-routes/errors/page.mdx": "2024-09-30T08:43:53.121Z",
|
||||
"app/learn/advanced-development/admin/constraints/page.mdx": "2024-09-10T11:39:51.165Z",
|
||||
"app/learn/fundamentals/modules/service-constraints/page.mdx": "2024-11-19T16:37:47.253Z",
|
||||
"app/learn/fundamentals/api-routes/responses/page.mdx": "2024-10-21T13:30:21.367Z",
|
||||
"app/learn/fundamentals/api-routes/validation/page.mdx": "2024-12-09T11:02:38.397Z",
|
||||
"app/learn/fundamentals/api-routes/errors/page.mdx": "2024-10-21T13:30:21.367Z",
|
||||
"app/learn/fundamentals/admin/constraints/page.mdx": "2024-10-21T13:30:21.366Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx": "2024-10-16T08:50:03.061Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2024-10-16T08:50:23.232Z",
|
||||
"app/learn/advanced-development/module-links/custom-columns/page.mdx": "2024-11-19T15:05:59.471Z",
|
||||
"app/learn/advanced-development/module-links/directions/page.mdx": "2024-09-16T15:37:51.441Z",
|
||||
"app/learn/advanced-development/module-links/page.mdx": "2024-09-16T15:36:48.190Z",
|
||||
"app/learn/advanced-development/module-links/query/page.mdx": "2024-11-19T15:25:01.149Z",
|
||||
"app/learn/advanced-development/module-links/remote-link/page.mdx": "2024-09-16T12:42:27.581Z",
|
||||
"app/learn/advanced-development/modules/db-operations/page.mdx": "2024-09-16T14:38:29.150Z",
|
||||
"app/learn/advanced-development/modules/multiple-services/page.mdx": "2024-09-16T14:41:32.975Z",
|
||||
"app/learn/advanced-development/modules/page.mdx": "2024-09-16T14:33:48.217Z",
|
||||
"app/learn/fundamentals/module-links/custom-columns/page.mdx": "2024-11-20T14:32:09.764Z",
|
||||
"app/learn/fundamentals/module-links/directions/page.mdx": "2024-10-21T13:30:21.369Z",
|
||||
"app/learn/fundamentals/module-links/page.mdx": "2024-10-28T04:22:27.541Z",
|
||||
"app/learn/fundamentals/module-links/query/page.mdx": "2024-12-09T10:38:41.169Z",
|
||||
"app/learn/fundamentals/module-links/remote-link/page.mdx": "2024-10-28T04:22:21.328Z",
|
||||
"app/learn/fundamentals/modules/db-operations/page.mdx": "2024-12-04T11:02:57.134Z",
|
||||
"app/learn/fundamentals/modules/multiple-services/page.mdx": "2024-10-21T13:30:21.370Z",
|
||||
"app/learn/fundamentals/modules/page.mdx": "2024-12-09T11:02:37.696Z",
|
||||
"app/learn/debugging-and-testing/instrumentation/page.mdx": "2024-09-17T08:53:15.910Z",
|
||||
"app/learn/advanced-development/api-routes/additional-data/page.mdx": "2024-09-30T08:43:53.120Z",
|
||||
"app/learn/advanced-development/workflows/page.mdx": "2024-09-18T08:00:57.364Z",
|
||||
"app/learn/advanced-development/workflows/variable-manipulation/page.mdx": "2024-11-14T16:11:24.538Z",
|
||||
"app/learn/customization/custom-features/api-route/page.mdx": "2024-11-28T13:12:10.521Z",
|
||||
"app/learn/customization/custom-features/module/page.mdx": "2024-11-28T09:25:29.098Z",
|
||||
"app/learn/customization/custom-features/workflow/page.mdx": "2024-12-06T14:34:53.354Z",
|
||||
"app/learn/customization/extend-features/extend-create-product/page.mdx": "2024-12-05T09:26:15.796Z",
|
||||
"app/learn/customization/custom-features/page.mdx": "2024-11-28T08:21:55.207Z",
|
||||
"app/learn/customization/customize-admin/page.mdx": "2024-12-06T07:21:02.303Z",
|
||||
"app/learn/customization/customize-admin/route/page.mdx": "2024-12-06T08:29:57.834Z",
|
||||
"app/learn/customization/customize-admin/widget/page.mdx": "2024-12-06T08:15:11.426Z",
|
||||
"app/learn/customization/extend-features/define-link/page.mdx": "2024-12-04T17:15:16.004Z",
|
||||
"app/learn/customization/extend-features/page.mdx": "2024-09-12T12:38:57.394Z",
|
||||
"app/learn/customization/extend-features/query-linked-records/page.mdx": "2024-12-05T10:36:32.357Z",
|
||||
"app/learn/customization/integrate-systems/handle-event/page.mdx": "2024-12-06T14:34:53.355Z",
|
||||
"app/learn/customization/integrate-systems/page.mdx": "2024-12-06T14:34:53.355Z",
|
||||
"app/learn/customization/integrate-systems/schedule-task/page.mdx": "2024-12-06T14:34:53.355Z",
|
||||
"app/learn/customization/integrate-systems/service/page.mdx": "2024-12-06T14:34:53.356Z",
|
||||
"app/learn/fundamentals/api-routes/additional-data/page.mdx": "2024-12-09T10:46:28.589Z",
|
||||
"app/learn/fundamentals/workflows/variable-manipulation/page.mdx": "2024-11-19T16:43:01.663Z",
|
||||
"app/learn/customization/custom-features/api-route/page.mdx": "2024-12-09T10:39:30.046Z",
|
||||
"app/learn/customization/custom-features/module/page.mdx": "2024-12-09T11:02:39.826Z",
|
||||
"app/learn/customization/custom-features/workflow/page.mdx": "2024-12-09T10:46:47.051Z",
|
||||
"app/learn/customization/extend-features/extend-create-product/page.mdx": "2024-12-09T11:02:39.423Z",
|
||||
"app/learn/customization/custom-features/page.mdx": "2024-12-09T10:46:28.593Z",
|
||||
"app/learn/customization/customize-admin/page.mdx": "2024-12-09T11:02:38.801Z",
|
||||
"app/learn/customization/customize-admin/route/page.mdx": "2024-12-09T11:02:38.969Z",
|
||||
"app/learn/customization/customize-admin/widget/page.mdx": "2024-12-09T11:02:39.108Z",
|
||||
"app/learn/customization/extend-features/define-link/page.mdx": "2024-12-09T11:02:39.346Z",
|
||||
"app/learn/customization/extend-features/page.mdx": "2024-12-09T11:02:39.244Z",
|
||||
"app/learn/customization/extend-features/query-linked-records/page.mdx": "2024-12-09T11:02:39.519Z",
|
||||
"app/learn/customization/integrate-systems/handle-event/page.mdx": "2024-12-09T11:02:39.744Z",
|
||||
"app/learn/customization/integrate-systems/page.mdx": "2024-12-09T10:40:08.528Z",
|
||||
"app/learn/customization/integrate-systems/schedule-task/page.mdx": "2024-12-09T10:52:19.379Z",
|
||||
"app/learn/customization/integrate-systems/service/page.mdx": "2024-12-09T11:02:39.594Z",
|
||||
"app/learn/customization/next-steps/page.mdx": "2024-12-06T14:34:53.356Z",
|
||||
"app/learn/customization/page.mdx": "2024-09-12T11:16:18.504Z",
|
||||
"app/learn/more-resources/cheatsheet/page.mdx": "2024-07-11T16:11:26.480Z",
|
||||
"app/learn/architecture/architectural-modules/page.mdx": "2024-09-23T12:51:04.520Z",
|
||||
"app/learn/architecture/overview/page.mdx": "2024-09-23T12:55:01.339Z",
|
||||
"app/learn/advanced-development/data-models/infer-type/page.mdx": "2024-09-30T08:43:53.123Z",
|
||||
"app/learn/advanced-development/custom-cli-scripts/seed-data/page.mdx": "2024-10-03T11:11:07.181Z",
|
||||
"app/learn/basics/modules/page.mdx": "2024-11-28T15:41:58.354Z",
|
||||
"app/learn/advanced-development/environment-variables/page.mdx": "2024-10-25T14:59:07.831Z",
|
||||
"app/learn/build/page.mdx": "2024-11-11T11:08:41.832Z",
|
||||
"app/learn/fundamentals/modules/architectural-modules/page.mdx": "2024-10-21T13:30:21.367Z",
|
||||
"app/learn/introduction/architecture/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/data-models/infer-type/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/custom-cli-scripts/seed-data/page.mdx": "2024-10-21T13:30:21.368Z",
|
||||
"app/learn/fundamentals/environment-variables/page.mdx": "2024-12-09T11:00:57.428Z",
|
||||
"app/learn/build/page.mdx": "2024-12-09T11:05:17.383Z",
|
||||
"app/learn/deployment/general/page.mdx": "2024-11-25T14:33:50.439Z",
|
||||
"app/learn/advanced-development/workflows/multiple-step-usage/page.mdx": "2024-11-12T11:11:49.191Z",
|
||||
"app/learn/installation/page.mdx": "2024-11-28T14:18:21.905Z",
|
||||
"app/learn/advanced-development/data-models/check-constraints/page.mdx": "2024-12-04T10:39:01.764Z"
|
||||
"app/learn/fundamentals/workflows/multiple-step-usage/page.mdx": "2024-11-25T16:19:32.169Z",
|
||||
"app/learn/installation/page.mdx": "2024-12-09T11:22:27.919Z",
|
||||
"app/learn/fundamentals/data-models/check-constraints/page.mdx": "2024-12-06T14:34:50.384Z"
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from "remark-rehype-plugins"
|
||||
import { sidebar } from "./sidebar.mjs"
|
||||
import path from "path"
|
||||
import redirects from "./utils/redirects.mjs"
|
||||
|
||||
const withMDX = mdx({
|
||||
extension: /\.mdx?$/,
|
||||
@@ -165,41 +166,7 @@ const nextConfig = {
|
||||
],
|
||||
}
|
||||
},
|
||||
async redirects() {
|
||||
return [
|
||||
{
|
||||
source: "/v2/:path*",
|
||||
destination: "/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/recipes/:path*",
|
||||
destination: "/resources/recipes",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/plugins/:path*",
|
||||
destination: "/v1/plugins/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/medusa-react/:path*",
|
||||
destination: "/v1/medusa-react/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/learn/customization/extend-models/:path*",
|
||||
destination: "/learn/customization/extend-features/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/learn/customization/extend-features/create-links",
|
||||
destination:
|
||||
"/learn/customization/extend-features/extend-create-product",
|
||||
permanent: true,
|
||||
},
|
||||
]
|
||||
},
|
||||
redirects,
|
||||
}
|
||||
|
||||
export default withMDX(nextConfig)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user