docs: typos and examples fixes (#11954)
* docs: typos and examples fixes * fix notification example
This commit is contained in:
@@ -45,7 +45,7 @@ The `moduleIntegrationTestRunner` function accepts as a parameter an object with
|
||||
|
||||
- `moduleName`: The name of the module.
|
||||
- `moduleModels`: An array of models in the module. Refer to [this section](#write-tests-for-modules-without-data-models) if your module doesn't have data models.
|
||||
- `resolve`: The path to the model.
|
||||
- `resolve`: The path to the module's directory.
|
||||
- `testSuite`: A function that defines the tests to run.
|
||||
|
||||
The `testSuite` function accepts as a parameter an object having the `service` property, which is an instance of the module's main service.
|
||||
|
||||
@@ -8,7 +8,7 @@ In this chapter, you'll learn how to use environment variables in your admin cus
|
||||
|
||||
<Note>
|
||||
|
||||
To learn how envirnment variables are generally loaded in Medusa based on your application's environment, check out [this chapter](../../environment-variables/page.mdx).
|
||||
To learn how environment variables are generally loaded in Medusa based on your application's environment, check out [this chapter](../../environment-variables/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ In this chapter, you’ll learn about middlewares and how to create them.
|
||||
|
||||
A middleware is a function executed when a request is sent to an API Route. It's executed before the route handler function.
|
||||
|
||||
Middlwares are used to guard API routes, parse request content types other than `application/json`, manipulate request data, and more.
|
||||
Middlewares are used to guard API routes, parse request content types other than `application/json`, manipulate request data, and more.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ For example, if you omit the `a` parameter, you'll receive a `400` response code
|
||||
|
||||
---
|
||||
|
||||
## How to Validate Request Query Paramters
|
||||
## How to Validate Request Query Parameters
|
||||
|
||||
The steps to validate the request query parameters are the similar to that of [validating the body](#how-to-validate-request-body).
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ You can also write migrations manually. To do that, create a file in the `migrat
|
||||
|
||||
For example:
|
||||
|
||||
```ts title="src/modules/blog/migrations/Migration20240429.ts"
|
||||
```ts title="src/modules/blog/migrations/Migration202507021059.ts"
|
||||
import { Migration } from "@mikro-orm/migrations"
|
||||
|
||||
export class Migration202507021059 extends Migration {
|
||||
|
||||
@@ -545,7 +545,7 @@ The middleware transforms these parameters to configurations that you can pass t
|
||||
|
||||
<Note>
|
||||
|
||||
As of [Medusa v2.2.0](https://github.com/medusajs/medusa/releases/tag/v2.2.0), `remoteQueryConfig` has been depercated in favor of `queryConfig`. Their usage is still the same, only the property name has changed.
|
||||
As of [Medusa v2.2.0](https://github.com/medusajs/medusa/releases/tag/v2.2.0), `remoteQueryConfig` has been deprecated in favor of `queryConfig`. Their usage is still the same, only the property name has changed.
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ export default async function helloWorldLoader({
|
||||
}: LoaderOptions) {
|
||||
const logger = container.resolve("logger")
|
||||
|
||||
logger.info("[helloWorldLoader]: Hello, World!")
|
||||
logger.info("[HELLO MODULE] Just started the Medusa application!")
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ const myWorkflow = createWorkflow(
|
||||
attachProductToSalesChannelStep(product)
|
||||
)
|
||||
|
||||
const id = product.id
|
||||
const refetchedProduct = getProductStep(product.id)
|
||||
|
||||
return new WorkflowResponse(refetchedProduct)
|
||||
|
||||
@@ -12,7 +12,7 @@ export const generatedEditDates = {
|
||||
"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-12-09T14:45:13.801Z",
|
||||
"app/learn/fundamentals/workflows/parallel-steps/page.mdx": "2025-03-24T06:53:36.918Z",
|
||||
"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",
|
||||
@@ -20,7 +20,7 @@ export const generatedEditDates = {
|
||||
"app/learn/fundamentals/events-and-subscribers/page.mdx": "2024-12-09T10:48:09.285Z",
|
||||
"app/learn/fundamentals/modules/container/page.mdx": "2025-03-18T15:10:03.574Z",
|
||||
"app/learn/fundamentals/workflows/execute-another-workflow/page.mdx": "2024-12-09T15:56:22.895Z",
|
||||
"app/learn/fundamentals/modules/loaders/page.mdx": "2024-12-09T10:32:29.221Z",
|
||||
"app/learn/fundamentals/modules/loaders/page.mdx": "2025-03-24T06:40:39.948Z",
|
||||
"app/learn/fundamentals/admin/widgets/page.mdx": "2024-12-09T16:43:24.260Z",
|
||||
"app/learn/fundamentals/data-models/page.mdx": "2025-03-18T07:55:56.252Z",
|
||||
"app/learn/fundamentals/modules/remote-link/page.mdx": "2024-09-30T08:43:53.127Z",
|
||||
@@ -34,7 +34,7 @@ export const generatedEditDates = {
|
||||
"app/learn/fundamentals/admin/page.mdx": "2025-03-21T08:25:13.754Z",
|
||||
"app/learn/fundamentals/workflows/long-running-workflow/page.mdx": "2025-03-18T08:02:14.085Z",
|
||||
"app/learn/fundamentals/workflows/constructor-constraints/page.mdx": "2025-02-12T13:55:33.437Z",
|
||||
"app/learn/fundamentals/data-models/write-migration/page.mdx": "2025-03-18T08:00:44.980Z",
|
||||
"app/learn/fundamentals/data-models/write-migration/page.mdx": "2025-03-24T06:41:48.915Z",
|
||||
"app/learn/fundamentals/data-models/manage-relationships/page.mdx": "2025-03-18T15:09:18.688Z",
|
||||
"app/learn/fundamentals/modules/remote-query/page.mdx": "2024-07-21T21:20:24+02:00",
|
||||
"app/learn/fundamentals/modules/options/page.mdx": "2025-03-18T15:12:34.510Z",
|
||||
@@ -48,7 +48,7 @@ export const generatedEditDates = {
|
||||
"app/learn/fundamentals/admin/tips/page.mdx": "2025-03-11T08:54:12.028Z",
|
||||
"app/learn/fundamentals/api-routes/cors/page.mdx": "2025-03-11T08:54:26.281Z",
|
||||
"app/learn/fundamentals/admin/ui-routes/page.mdx": "2025-02-24T09:35:11.752Z",
|
||||
"app/learn/fundamentals/api-routes/middlewares/page.mdx": "2025-03-04T10:16:15.029Z",
|
||||
"app/learn/fundamentals/api-routes/middlewares/page.mdx": "2025-03-24T06:43:02.362Z",
|
||||
"app/learn/fundamentals/modules/isolation/page.mdx": "2024-12-09T11:02:38.087Z",
|
||||
"app/learn/fundamentals/data-models/index/page.mdx": "2025-03-18T07:59:07.798Z",
|
||||
"app/learn/fundamentals/custom-cli-scripts/page.mdx": "2024-10-23T07:08:55.898Z",
|
||||
@@ -60,15 +60,15 @@ export const generatedEditDates = {
|
||||
"app/learn/debugging-and-testing/testing-tools/unit-tests/page.mdx": "2024-09-02T11:03:26.997Z",
|
||||
"app/learn/fundamentals/modules/service-constraints/page.mdx": "2025-03-18T15:12:46.006Z",
|
||||
"app/learn/fundamentals/api-routes/responses/page.mdx": "2024-10-21T13:30:21.367Z",
|
||||
"app/learn/fundamentals/api-routes/validation/page.mdx": "2024-12-09T13:04:02.426Z",
|
||||
"app/learn/fundamentals/api-routes/validation/page.mdx": "2025-03-24T06:52:47.896Z",
|
||||
"app/learn/fundamentals/api-routes/errors/page.mdx": "2024-12-09T16:44:19.781Z",
|
||||
"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": "2025-03-18T15:07:22.640Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2025-03-18T15:08:42.198Z",
|
||||
"app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2025-03-24T06:54:21.249Z",
|
||||
"app/learn/fundamentals/module-links/custom-columns/page.mdx": "2025-03-11T13:29:54.752Z",
|
||||
"app/learn/fundamentals/module-links/directions/page.mdx": "2025-03-17T12:52:06.161Z",
|
||||
"app/learn/fundamentals/module-links/page.mdx": "2025-03-11T13:39:14.345Z",
|
||||
"app/learn/fundamentals/module-links/query/page.mdx": "2025-03-21T09:14:54.943Z",
|
||||
"app/learn/fundamentals/module-links/query/page.mdx": "2025-03-24T06:42:32.337Z",
|
||||
"app/learn/fundamentals/modules/db-operations/page.mdx": "2025-03-21T09:21:46.901Z",
|
||||
"app/learn/fundamentals/modules/multiple-services/page.mdx": "2025-03-18T15:11:44.632Z",
|
||||
"app/learn/fundamentals/modules/page.mdx": "2025-03-18T07:51:09.049Z",
|
||||
@@ -108,7 +108,7 @@ export const generatedEditDates = {
|
||||
"app/learn/customization/reuse-customizations/page.mdx": "2025-01-22T10:01:57.665Z",
|
||||
"app/learn/update/page.mdx": "2025-01-27T08:45:19.030Z",
|
||||
"app/learn/fundamentals/module-links/query-context/page.mdx": "2025-02-12T16:59:20.963Z",
|
||||
"app/learn/fundamentals/admin/environment-variables/page.mdx": "2025-02-18T14:48:17.731Z",
|
||||
"app/learn/fundamentals/admin/environment-variables/page.mdx": "2025-03-24T06:52:16.903Z",
|
||||
"app/learn/fundamentals/api-routes/parse-body/page.mdx": "2025-02-14T08:32:25.596Z",
|
||||
"app/learn/fundamentals/admin/routing/page.mdx": "2025-02-24T09:50:37.495Z",
|
||||
"app/learn/resources/contribution-guidelines/admin-translations/page.mdx": "2025-02-11T16:57:46.726Z",
|
||||
|
||||
@@ -1005,7 +1005,7 @@ export const generatedSidebars = [
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"title": "Type Aliases",
|
||||
"path": "/learn/conventions/ts-aliases",
|
||||
"path": "/learn/configurations/ts-aliases",
|
||||
"children": [],
|
||||
"chapterTitle": "6.3. Type Aliases",
|
||||
"number": "6.3."
|
||||
@@ -1213,7 +1213,7 @@ export const generatedSidebars = [
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/learn/resources//contribution-guidelines/admin-translations",
|
||||
"path": "/learn/resources/contribution-guidelines/admin-translations",
|
||||
"title": "Admin Translations",
|
||||
"children": [],
|
||||
"chapterTitle": "10.1.2. Admin Translations",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -527,7 +527,7 @@ export const sidebars = [
|
||||
{
|
||||
type: "link",
|
||||
title: "Type Aliases",
|
||||
path: "/learn/conventions/ts-aliases",
|
||||
path: "/learn/configurations/ts-aliases",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -640,7 +640,7 @@ export const sidebars = [
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/learn/resources//contribution-guidelines/admin-translations",
|
||||
path: "/learn/resources/contribution-guidelines/admin-translations",
|
||||
title: "Admin Translations",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -116,15 +116,15 @@ Refer to [this SendGrid documentation guide](https://docs.sendgrid.com/ui/sendin
|
||||
To test the module out, create a simple subscriber at `src/subscribers/product-created.ts` with the following content:
|
||||
|
||||
export const highlights = [
|
||||
["12", "notificationModuleService", "Resolve the Notification Module."],
|
||||
["15", "create", "Create the notification to be sent."],
|
||||
["11", "notificationModuleService", "Resolve the Notification Module."],
|
||||
["13", "createNotifications", "Create the notification to be sent."],
|
||||
[
|
||||
"17",
|
||||
"15",
|
||||
'"email"',
|
||||
"By specifying the `email` channel, SendGrid will be used to send the notification.",
|
||||
],
|
||||
["18", '"product-created"', "The ID of the template defined in SendGrid."],
|
||||
["19", "data", "The data to pass to the template defined in SendGrid."],
|
||||
["16", '"product-created"', "The ID of the template defined in SendGrid."],
|
||||
["17", "data", "The data to pass to the template defined in SendGrid."],
|
||||
]
|
||||
|
||||
```ts title="src/subscribers/product-created.ts" highlights={highlights} collapsibleLines="1-7" expandButtonLabel="Show Imports"
|
||||
@@ -133,30 +133,24 @@ import type {
|
||||
SubscriberConfig,
|
||||
} from "@medusajs/framework"
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
import { INotificationModuleService } from "@medusajs/framework/types"
|
||||
|
||||
export default async function productCreateHandler({
|
||||
event: { data },
|
||||
container,
|
||||
}: SubscriberArgs<{ id: string }>) {
|
||||
const notificationModuleService: INotificationModuleService =
|
||||
container.resolve(Modules.NOTIFICATION)
|
||||
const notificationModuleService = container.resolve(Modules.NOTIFICATION)
|
||||
const productModuleService = container.resolve(Modules.PRODUCT)
|
||||
|
||||
const product = await productModuleService.retrieveProduct(data.id)
|
||||
|
||||
await notificationModuleService.createNotifications({
|
||||
to: "test@gmail.com",
|
||||
from: "test@medusajs.com", // Optional var, verified sender required
|
||||
channel: "email",
|
||||
template: "product-created",
|
||||
data,
|
||||
attachments: [ // optional var
|
||||
{
|
||||
content: base64,
|
||||
content_type: "image/png", // mime type
|
||||
filename: filename.ext,
|
||||
disposition: "attachment or inline attachment",
|
||||
id: "id", // only needed for inline attachment
|
||||
},
|
||||
],
|
||||
data: {
|
||||
product_title: product.title,
|
||||
product_image: product.images[0]?.url,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -165,15 +159,13 @@ export const config: SubscriberConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
In this subscriber:
|
||||
In this subscriber, you:
|
||||
|
||||
- Resolve the Notification Module's main service.
|
||||
- Use the `create` method of the main service to create a notification to be sent to the specified email.
|
||||
- By specifying the `email` channel, the SendGrid Notification Module Provider is used to send the notification.
|
||||
- The `template` property of the `create` method's parameter specifies the ID of the template defined in SendGrid.
|
||||
- The `data` property allows you to pass data to the template in SendGrid.
|
||||
- The `attachments` optional property allows you to pass attachments to the template in SendGrid.
|
||||
- The `from` optional property allows you to pass a single sender-verified email. If not provided, the value of the `from` configuration of the module is used.
|
||||
- Resolve the Notification and Product Modules' main services from the [Medusa container](!docs!/learn/fundamentals/medusa-container).
|
||||
- Retrieve the product's details to pass them to the template in SendGrid.
|
||||
- Use the `createNotifications` method of the Notification Module's main service to create a notification to be sent to the specified email. By specifying the `email` channel, the SendGrid Notification Module Provider is used to send the notification.
|
||||
- The `template` property of the `createNotifications` method's parameter specifies the ID of the template defined in SendGrid.
|
||||
- The `data` property allows you to pass data to the template in SendGrid. For example, the product's title and image.
|
||||
|
||||
Then, start the Medusa application:
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ export const generatedEditDates = {
|
||||
"app/commerce-modules/auth/create-actor-type/page.mdx": "2024-12-25T13:26:27.176Z",
|
||||
"app/architectural-modules/page.mdx": "2025-03-12T10:28:44.544Z",
|
||||
"app/architectural-modules/workflow-engine/redis/page.mdx": "2024-10-15T12:50:59.507Z",
|
||||
"app/architectural-modules/notification/sendgrid/page.mdx": "2025-02-26T11:43:13.143Z",
|
||||
"app/architectural-modules/notification/sendgrid/page.mdx": "2025-03-24T07:01:32.437Z",
|
||||
"app/commerce-modules/api-key/concepts/page.mdx": "2024-10-07T13:59:37.529Z",
|
||||
"app/architectural-modules/workflow-engine/page.mdx": "2025-03-12T11:55:18.789Z",
|
||||
"app/_events-reference/page.mdx": "2024-07-03T19:27:13+03:00",
|
||||
|
||||
@@ -3,19 +3,14 @@ import { CodeBlock, Label } from "@medusajs/ui"
|
||||
const snippets = [
|
||||
{
|
||||
label: "cURL",
|
||||
language: "markdown",
|
||||
code: `curl -H 'x-publishable-key: YOUR_API_KEY' 'http://localhost:9000/store/products/PRODUCT_ID'`,
|
||||
language: "bash",
|
||||
code: `curl 'http://localhost:9000/store/products/PRODUCT_ID'\n -H 'x-publishable-key: YOUR_API_KEY'`,
|
||||
hideLineNumbers: true,
|
||||
},
|
||||
{
|
||||
label: "Medusa JS Client",
|
||||
label: "Medusa JS SDK",
|
||||
language: "jsx",
|
||||
code: `// Install the JS Client in your storefront project: @medusajs/medusa-js\n\nimport Medusa from "@medusajs/medusa-js"\n\nconst medusa = new Medusa({ publishableApiKey: "YOUR_API_KEY"})\nconst product = await medusa.products.retrieve("PRODUCT_ID")\nconsole.log(product.id)`,
|
||||
},
|
||||
{
|
||||
label: "Medusa React",
|
||||
language: "tsx",
|
||||
code: `// Install the React SDK and required dependencies in your storefront project:\n// medusa-react @tanstack/react-query @medusajs/medusa\n\nimport { useProduct } from "medusa-react"\n\nconst { product } = useProduct("PRODUCT_ID")\nconsole.log(product.id)`,
|
||||
code: `// Install the JS SDK in your storefront project: @medusajs/js-sdk\n\nimport Medusa from "@medusajs/js-sdk"\n\nconst medusa = new Medusa({\n baseUrl: import.meta.env.NEXT_PUBLIC_BACKEND_URL || "/",\n publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PAK\n})\nconst { product } = await medusa.store.products.retrieve("prod_123")\nconsole.log(product.id)`,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ import { CodeBlock } from "@medusajs/ui"
|
||||
|
||||
const snippets = [
|
||||
{
|
||||
label: "Medusa React",
|
||||
language: "tsx",
|
||||
code: `import { useProduct } from "medusa-react"\n\nconst { product } = useProduct("PRODUCT_ID")\nconsole.log(product.id)`,
|
||||
label: "Medusa JS SDK",
|
||||
language: "jsx",
|
||||
code: `// Install the JS SDK in your storefront project: @medusajs/js-sdk\n\nimport Medusa from "@medusajs/js-sdk"\n\nconst medusa = new Medusa({\n baseUrl: import.meta.env.NEXT_PUBLIC_BACKEND_URL || "/",\n publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PAK\n})\nconst { product } = await medusa.store.products.retrieve("prod_123")\nconsole.log(product.id)`,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -2,10 +2,9 @@ import { CodeBlock, Label } from "@medusajs/ui"
|
||||
|
||||
const snippets = [
|
||||
{
|
||||
label: "Medusa React",
|
||||
language: "tsx",
|
||||
code: `import { useProduct } from "medusa-react"\n\nconst { product } = useProduct("PRODUCT_ID")\nconsole.log(product.id)`,
|
||||
hideLineNumbers: true,
|
||||
label: "Medusa JS SDK",
|
||||
language: "jsx",
|
||||
code: `// Install the JS SDK in your storefront project: @medusajs/js-sdk\n\nimport Medusa from "@medusajs/js-sdk"\n\nconst medusa = new Medusa({\n baseUrl: import.meta.env.NEXT_PUBLIC_BACKEND_URL || "/",\n publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PAK\n})\nconst { product } = await medusa.store.products.retrieve("prod_123")\nconsole.log(product.id)`,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ import { CodeBlock, Label } from "@medusajs/ui"
|
||||
|
||||
const snippets = [
|
||||
{
|
||||
label: "Medusa React",
|
||||
language: "tsx",
|
||||
code: `import { useProduct } from "medusa-react"\n\nconst { product } = useProduct("PRODUCT_ID")\nconsole.log(product.id)`,
|
||||
label: "Medusa JS SDK",
|
||||
language: "jsx",
|
||||
code: `// Install the JS SDK in your storefront project: @medusajs/js-sdk\n\nimport Medusa from "@medusajs/js-sdk"\n\nconst medusa = new Medusa({\n baseUrl: import.meta.env.NEXT_PUBLIC_BACKEND_URL || "/",\n publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PAK\n})\nconst { product } = await medusa.store.products.retrieve("prod_123")\nconsole.log(product.id)`,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user