docs: add keywords to cloud, fixes to installation and Index Module docs (#14129)

* docs: add keywords to cloud, fixes to installation and Index Module docs

* fix vale error
This commit is contained in:
Shahed Nasser
2025-11-26 14:36:29 +02:00
committed by GitHub
parent 458dc9d22b
commit 76660fb6cc
6 changed files with 69 additions and 56 deletions

View File

@@ -28,7 +28,7 @@ The Index Module solves this problem by ingesting data into a central data store
### Ingested Data Models
All core data models in Medusa are ingested, including `Product`, `Price`, `SalesChannel`, and more. You can also index custom data models if they are linked to an ingested data model. You'll learn more about this in the [Ingest Custom Data Models](#how-to-ingest-custom-data-models) section.
Data models are ingested if they're linked to other data models with the `filterable` property set, as you'll learn in the [Ingest Custom Data Models](#how-to-ingest-custom-data-models) section. Medusa also ingests some core data models by default, such as `Product`, `ProductVariant`, `Price`, and `SalesChannel`.
<Note>
@@ -68,7 +68,7 @@ npx medusa db:migrate
### Ingest Data
The Index Module only ingests data when you start your Medusa server. So, to ingest the [currently supported data models](#ingested-data-models), start the Medusa application:
The Index Module only ingests data when you start your Medusa server. So, to [ingest data models](#ingested-data-models), start the Medusa application:
```bash npm2yarn
npm run dev
@@ -177,7 +177,7 @@ The `index` method accepts an object with the same properties as the `graph` met
## How to Ingest Custom Data Models
Aside from the [core data models](#ingested-data-models), you can also ingest your own custom data models into the Index Module. You can do so by defining a link between your custom data model and one of the core data models, and setting the `filterable` property in the link definition.
You can ingest core and custom data models into the Index Module. You can do so by defining a link between your custom data model and one of the core data models, and setting the `filterable` property in the link definition.
<Note>
@@ -185,7 +185,7 @@ Read-only links are not supported by the Index Module.
</Note>
For example, assuming you have a Brand Module with a Brand data model (as explained in the [Customizations](../../../customization/custom-features/module/page.mdx)), you can ingest it into the Index Module using the `filterable` property in its link definition to the Product data model:
For example, assuming you have a Brand Module with a Brand data model (as explained in the [Customizations](../../../customization/custom-features/module/page.mdx)), you can ingest it into the Index Module using the `filterable` property in its link definition to the `Product` data model:
export const filterableHighlights = [
["12", "filterable", "Ingest Brand by setting its filterable properties."]

View File

@@ -10,15 +10,15 @@ In this chapter, you'll learn how to install and run a Medusa application.
## Get Started with Cloud
Cloud is Medusa's PaaS platform that allows you to deploy and manage production-ready Medusa applications with ease. Benefit from features like zero-configuration deployments, automatic scaling, and GitHub integration to streamline your development workflow.
[Cloud](!cloud!) is Medusa's PaaS platform that allows you to deploy and manage production-ready Medusa applications with ease. Benefit from features like zero-configuration deployments, automatic scaling, and GitHub integration to streamline your development workflow.
Refer to the [Sign Up](!cloud!/sign-up) guide to create your first Medusa project in minutes.
[Sign up](http://cloud.medusajs.com/signup) with Cloud and create your first Medusa project in minutes.
---
## Create Medusa Application Locally
A Medusa application is made up of a Node.js server and an admin dashboard. You can optionally install the [Next.js Starter Storefront](!resources!/nextjs-starter) separately either while installing the Medusa application or at a later point.
A Medusa application is made up of a Node.js server and a Vite admin dashboard. You can optionally install the [Next.js Starter Storefront](!resources!/nextjs-starter) separately either while installing the Medusa application or at a later point.
<Note>

View File

@@ -96,7 +96,7 @@ export const generatedEditDates = {
"app/learn/build/page.mdx": "2025-10-27T09:30:26.957Z",
"app/learn/deployment/general/page.mdx": "2025-10-21T07:39:08.998Z",
"app/learn/fundamentals/workflows/multiple-step-usage/page.mdx": "2025-08-01T14:59:59.501Z",
"app/learn/installation/page.mdx": "2025-10-24T09:22:44.583Z",
"app/learn/installation/page.mdx": "2025-11-26T12:14:47.372Z",
"app/learn/fundamentals/data-models/check-constraints/page.mdx": "2025-07-25T13:50:21.065Z",
"app/learn/fundamentals/module-links/link/page.mdx": "2025-04-07T08:03:14.513Z",
"app/learn/fundamentals/workflows/store-executions/page.mdx": "2025-04-17T08:29:10.166Z",
@@ -121,7 +121,7 @@ export const generatedEditDates = {
"app/learn/fundamentals/workflows/errors/page.mdx": "2025-04-25T14:26:25.000Z",
"app/learn/fundamentals/api-routes/override/page.mdx": "2025-05-09T08:01:24.493Z",
"app/learn/fundamentals/module-links/index/page.mdx": "2025-05-23T07:57:58.958Z",
"app/learn/fundamentals/module-links/index-module/page.mdx": "2025-10-30T11:31:29.704Z",
"app/learn/fundamentals/module-links/index-module/page.mdx": "2025-11-26T11:20:25.961Z",
"app/learn/introduction/build-with-llms-ai/page.mdx": "2025-10-02T15:10:49.394Z",
"app/learn/installation/docker/page.mdx": "2025-10-24T08:53:46.445Z",
"app/learn/fundamentals/generated-types/page.mdx": "2025-07-25T13:17:35.319Z",

View File

@@ -14684,7 +14684,7 @@ The Index Module solves this problem by ingesting data into a central data store
### Ingested Data Models
All core data models in Medusa are ingested, including `Product`, `Price`, `SalesChannel`, and more. You can also index custom data models if they are linked to an ingested data model. You'll learn more about this in the [Ingest Custom Data Models](#how-to-ingest-custom-data-models) section.
Data models are ingested if they're linked to other data models with the `filterable` property set, as you'll learn in the [Ingest Custom Data Models](#how-to-ingest-custom-data-models) section. Medusa also ingests some core data models by default, such as `Product`, `ProductVariant`, `Price`, and `SalesChannel`.
Prior to [Medusa v2.10.2](https://github.com/medusajs/medusa/releases/tag/v2.10.2), only the `Product`, `ProductVariant`, `Price`, and `SalesChannel` data models were ingested. Make sure to update to the latest version to ingest all core data models.
@@ -14720,7 +14720,7 @@ npx medusa db:migrate
### Ingest Data
The Index Module only ingests data when you start your Medusa server. So, to ingest the [currently supported data models](#ingested-data-models), start the Medusa application:
The Index Module only ingests data when you start your Medusa server. So, to [ingest data models](#ingested-data-models), start the Medusa application:
```bash npm2yarn
npm run dev
@@ -14825,11 +14825,11 @@ The `index` method accepts an object with the same properties as the `graph` met
## How to Ingest Custom Data Models
Aside from the [core data models](#ingested-data-models), you can also ingest your own custom data models into the Index Module. You can do so by defining a link between your custom data model and one of the core data models, and setting the `filterable` property in the link definition.
You can ingest core and custom data models into the Index Module. You can do so by defining a link between your custom data model and one of the core data models, and setting the `filterable` property in the link definition.
Read-only links are not supported by the Index Module.
For example, assuming you have a Brand Module with a Brand data model (as explained in the [Customizations](https://docs.medusajs.com/learn/customization/custom-features/module/index.html.md)), you can ingest it into the Index Module using the `filterable` property in its link definition to the Product data model:
For example, assuming you have a Brand Module with a Brand data model (as explained in the [Customizations](https://docs.medusajs.com/learn/customization/custom-features/module/index.html.md)), you can ingest it into the Index Module using the `filterable` property in its link definition to the `Product` data model:
```ts title="src/links/product-brand.ts" highlights={filterableHighlights}
import BrandModule from "../modules/brand"
@@ -24296,15 +24296,15 @@ In this chapter, you'll learn how to install and run a Medusa application.
## Get Started with Cloud
Cloud is Medusa's PaaS platform that allows you to deploy and manage production-ready Medusa applications with ease. Benefit from features like zero-configuration deployments, automatic scaling, and GitHub integration to streamline your development workflow.
[Cloud](https://docs.medusajs.com/cloud/index.html.md) is Medusa's PaaS platform that allows you to deploy and manage production-ready Medusa applications with ease. Benefit from features like zero-configuration deployments, automatic scaling, and GitHub integration to streamline your development workflow.
Refer to the [Sign Up](https://docs.medusajs.com/cloud/sign-up/index.html.md) guide to create your first Medusa project in minutes.
[Sign up](http://cloud.medusajs.com/signup) with Cloud and create your first Medusa project in minutes.
***
## Create Medusa Application Locally
A Medusa application is made up of a Node.js server and an admin dashboard. You can optionally install the [Next.js Starter Storefront](https://docs.medusajs.com/resources/nextjs-starter/index.html.md) separately either while installing the Medusa application or at a later point.
A Medusa application is made up of a Node.js server and a Vite admin dashboard. You can optionally install the [Next.js Starter Storefront](https://docs.medusajs.com/resources/nextjs-starter/index.html.md) separately either while installing the Medusa application or at a later point.
While this is the recommended way to create a Medusa application, you can alternatively [install a Medusa application with Docker](https://docs.medusajs.com/learn/installation/docker/index.html.md).
@@ -65737,7 +65737,7 @@ export const TierRule = model.define("tier_rule", {
{
on: ["tier_id", "currency_code"],
unique: true,
}
},
])
```
@@ -65876,7 +65876,7 @@ import CustomerModule from "@medusajs/medusa/customer"
export default defineLink(
{
linkable: TierModule.linkable.tier,
filterable: ["id"]
filterable: ["id"],
},
{
linkable: CustomerModule.linkable.customer,
@@ -66018,7 +66018,7 @@ export const createTierRulesStep = createStep(
const tierModuleService = container.resolve(TIER_MODULE)
const createdRules = await tierModuleService.createTierRules(
input.tier_rules.map(rule => ({
input.tier_rules.map((rule) => ({
tier_id: input.tier_id,
min_purchase_value: rule.min_purchase_value,
currency_code: rule.currency_code,
@@ -66033,7 +66033,7 @@ export const createTierRulesStep = createStep(
}
const tierModuleService = container.resolve(TIER_MODULE)
await tierModuleService.deleteTierRules(createdRules.map(rule => rule.id))
await tierModuleService.deleteTierRules(createdRules.map((rule) => rule.id))
}
)
```
@@ -66082,7 +66082,7 @@ export const createTierWorkflow = createWorkflow(
},
options: {
throwIfKeyNotFound: true,
}
},
})
})
// Create the tier
@@ -67005,7 +67005,7 @@ export const deleteTierRulesStep = createStep(
const tierModuleService: TierModuleService = container.resolve(TIER_MODULE)
// Restore deleted rules
await tierModuleService.createTierRules(
compensationData.map(rule => ({
compensationData.map((rule) => ({
tier_id: rule.tier_id,
min_purchase_value: rule.min_purchase_value,
currency_code: rule.currency_code,
@@ -67060,7 +67060,7 @@ export const updateTierWorkflow = createWorkflow(
},
options: {
throwIfKeyNotFound: true,
}
},
})
// Validate promotion if provided
when({ input }, (data) => !!data.input.promo_id)
@@ -67073,7 +67073,7 @@ export const updateTierWorkflow = createWorkflow(
},
options: {
throwIfKeyNotFound: true,
}
},
}).config({ name: "retrieve-promotion" })
})
// Update the tier
@@ -67089,10 +67089,10 @@ export const updateTierWorkflow = createWorkflow(
const ids = transform({
tiers,
}, (data) => {
return (data.tiers[0].tier_rules?.map(rule => rule?.id) || []) as string[]
return (data.tiers[0].tier_rules?.map((rule) => rule?.id) || []) as string[]
})
deleteTierRulesStep({
ids
ids,
})
return createTierRulesStep({
tier_id: input.id,
@@ -67205,8 +67205,8 @@ export default defineMiddlewares({
matcher: "/admin/tiers/:id",
methods: ["POST"],
middlewares: [validateAndTransformBody(UpdateTierSchema)],
}
]
},
],
})
```
@@ -67288,7 +67288,7 @@ export default defineMiddlewares({
}),
],
},
]
],
})
```
@@ -67319,8 +67319,8 @@ export default config({
// ...
{
resolve: "@medusajs/index",
}
]
},
],
})
```
@@ -67426,7 +67426,7 @@ const { data: storeData } = useQuery({
const updateTierMutation = useMutation({
mutationFn: async (data: EditTierFormData) => {
if (!tier) return
if (!tier) {return}
return await sdk.client.fetch(`/admin/tiers/${tier.id}`, {
method: "POST",
body: data,
@@ -67984,7 +67984,7 @@ In `src/admin/routes/tiers/page.tsx`, find the `onRowClick` handler and replace
```tsx title="src/admin/routes/tiers/page.tsx"
onRowClick: (_event, row) => {
navigate(`/tiers/${row.id}`)
},
}
```
You navigate to the tier details page when the user clicks on a tier in the tiers list.
@@ -68042,12 +68042,12 @@ class TierModuleService extends MedusaService({
}) {
async calculateQualifyingTier(
currencyCode: string,
purchaseValue: number,
purchaseValue: number
) {
const rules = await this.listTierRules(
{
currency_code: currencyCode,
},
}
)
if (!rules || rules.length === 0) {
@@ -68205,7 +68205,7 @@ export const updateCustomerTierOnOrderWorkflow = createWorkflow(
},
options: {
throwIfKeyNotFound: true,
}
},
})
const validatedCustomer = validateCustomerStep({
@@ -68223,8 +68223,8 @@ export const updateCustomerTierOnOrderWorkflow = createWorkflow(
$nin: [
OrderStatus.CANCELED,
OrderStatus.DRAFT,
]
}
],
},
},
}).config({ name: "completed-orders" })
@@ -68638,8 +68638,8 @@ updateCartPromotionsWorkflow.hooks.validate(async ({ input, cart }, { container
entity: "tier",
fields: ["id", "promo_id"],
filters: {
promo_id: promotions.map((p) => p.id)
}
promo_id: promotions.map((p) => p.id),
},
})
// Validate each promotion being added
@@ -68714,8 +68714,8 @@ completeCartWorkflow.hooks.validate(async ({ cart }, { container }) => {
entity: "tier",
fields: ["id", "promo_id"],
filters: {
promo_id: detailedCart.promotions.map((p) => p?.id).filter(Boolean) as string[]
}
promo_id: detailedCart.promotions.map((p) => p?.id).filter(Boolean) as string[],
},
})
// Validate that if a tier promotion is applied, the customer belongs to that tier
@@ -68761,7 +68761,7 @@ class TierModuleService extends MedusaService({
// ...
async calculateNextTierUpgrade(
currencyCode: string,
currentPurchaseValue: number,
currentPurchaseValue: number
) {
const rules = await this.listTierRules(
{
@@ -68866,7 +68866,7 @@ export async function GET(
// Get currency code from cart or region context
// Try to get from cart first, then region
let regionId = req.validatedQuery.region_id
const regionId = req.validatedQuery.region_id
// Calculate total purchase value
const { data: orders } = await query.graph({
@@ -68879,7 +68879,7 @@ export async function GET(
$nin: [
OrderStatus.CANCELED,
OrderStatus.DRAFT,
]
],
},
},
})
@@ -68911,7 +68911,7 @@ export async function GET(
const currentTier = customer.tier || null
// Determine next tier upgrade
let nextTierUpgrade = await tierModuleService.calculateNextTierUpgrade(
const nextTierUpgrade = await tierModuleService.calculateNextTierUpgrade(
currencyCode as string,
totalPurchaseValue
)
@@ -69018,9 +69018,9 @@ export const retrieveCustomerNextTier =
const authHeaders = await getAuthHeaders()
const region = await getRegion(countryCode)
if (!region) return null
if (!region) {return null}
if (!authHeaders) return null
if (!authHeaders) {return null}
const headers = {
...authHeaders,
@@ -69037,7 +69037,7 @@ export const retrieveCustomerNextTier =
next,
query: {
region_id: region.id,
}
},
})
.then((data) => data)
.catch(() => null)
@@ -94107,7 +94107,7 @@ To create the workflow, create the file `src/workflows/sync-products.ts` with th
import {
createWorkflow,
transform,
WorkflowResponse
WorkflowResponse,
} from "@medusajs/framework/workflows-sdk"
import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
import { syncProductsStep, SyncProductsStepInput } from "./steps/sync-products"
@@ -94123,11 +94123,11 @@ export const syncProductsWorkflow = createWorkflow(
"sync-products",
({ filters, limit, offset }: SyncProductsWorkflowInput) => {
const productFilters = transform({
filters
filters,
}, (data) => {
return {
status: ProductStatus.PUBLISHED,
...data.filters
...data.filters,
}
})
const { data, metadata } = useQueryGraphStep({
@@ -101971,7 +101971,7 @@ To create the workflow, create the file `src/workflows/sync-products.ts` with th
import {
createWorkflow,
transform,
WorkflowResponse
WorkflowResponse,
} from "@medusajs/framework/workflows-sdk"
import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
import { syncProductsStep, SyncProductsStepInput } from "./steps/sync-products"
@@ -101987,11 +101987,11 @@ export const syncProductsWorkflow = createWorkflow(
"sync-products",
({ filters, limit, offset }: SyncProductsWorkflowInput) => {
const productFilters = transform({
filters
filters,
}, (data) => {
return {
status: ProductStatus.PUBLISHED,
...data.filters
...data.filters,
}
})
const { data, metadata } = useQueryGraphStep({

View File

@@ -1,3 +1,16 @@
---
keywords:
- email
- mail
- medusa mail
- transactional email
- marketing email
- email service
- cloud email
- medusa cloud email
- medusa emails
---
import { CodeTabs, CodeTab, Prerequisites, InlineIcon } from "docs-ui"
import { ChevronUpDown } from "@medusajs/icons"

View File

@@ -26,6 +26,6 @@ export const generatedEditDates = {
"app/billing/plans/page.mdx": "2025-10-08T14:49:27.009Z",
"app/cache/page.mdx": "2025-11-12T14:37:24.809Z",
"app/deployments/troubleshooting/page.mdx": "2025-10-17T14:44:22.894Z",
"app/emails/page.mdx": "2025-11-12T15:41:36.777Z",
"app/emails/page.mdx": "2025-11-26T11:07:58.083Z",
"app/emails/react-email/page.mdx": "2025-11-12T15:41:56.365Z"
}