@@ -303,7 +303,7 @@ Medusa allows you to create custom API Routes exposed as REST APIs.
Then add the `requireCustomerAuthentication` middleware in `src/api/middlewares.ts` that ensures only authenticated customer can access this API Route:
@@ -105,7 +105,7 @@ Medusa also provides official notification plugins that integrate with third-par
Here’s an example of a subscriber that uses the SendGrid plugin to send an email to the customer when the order has a new note:
```ts title=src/subscribers/new-note.ts
```ts title="src/subscribers/new-note.ts"
import {
type SubscriberConfig,
type SubscriberArgs,
@@ -190,7 +190,7 @@ You can implement automatic synchronization in Medusa using scheduled jobs. A sc
Here’s an example of synchronizing products with a third party service using a [loader](../development/loaders/create.md):
```ts title=src/loaders/sync-products.ts
```ts title="src/loaders/sync-products.ts"
import {
Logger,
ProductService,
@@ -409,7 +409,7 @@ For example, if you're grouping customers with over twenty orders, you can use a
Here’s an example of a subscriber that listens to the `order.placed` event and checks if the customer should be added to the VIP customer group based on their number of orders:
@@ -575,7 +575,7 @@ To add an interface that allows the admin user to upload digital products, you c
You also need to create types for the expected requests and responses of the API Routes you created. This is helpful when using Medusa React’s custom hooks. To do that, create the file `src/types/product-media.ts` with the following content:
```ts title=src/types/product-media.ts
```ts title="src/types/product-media.ts"
import {
MediaType,
ProductMedia,
@@ -605,7 +605,7 @@ To add an interface that allows the admin user to upload digital products, you c
You can now create your admin UI route. To do that, create the file `src/admin/routes/product-media/page.tsx` with the following content:
import { useAdminCustomQuery } from "medusa-react"
@@ -714,7 +714,7 @@ To add an interface that allows the admin user to upload digital products, you c
In the drawer, you show the Create Digital Product form. To create this form, create the file `src/admin/components/product-media/CreateForm/index.tsx` with the following content:
@@ -1095,7 +1095,7 @@ To implement this, create a storefront API Route that allows you to fetch the di
First, if you're using TypeScript for your development, create the file `src/types/product-media.ts` with the following content:
```ts title=src/types/product-media.ts
```ts title="src/types/product-media.ts"
import { Product } from "@medusajs/medusa"
import { ProductVariant } from "@medusajs/product"
@@ -1132,7 +1132,7 @@ To implement this, create a storefront API Route that allows you to fetch the di
Then, add in `src/lib/data/index.ts` a new function that retrieves the product media of the product variant being viewed:
```ts title=src/lib/data/index.ts
```ts title="src/lib/data/index.ts"
import {
DigitalProduct,
ProductMedia,
@@ -1165,7 +1165,7 @@ To implement this, create a storefront API Route that allows you to fetch the di
To allow customers to download the file preview without exposing its URL, create a Next.js API route in the file `src/app/api/download/preview/route.ts` with the following content:
import Button from "@modules/common/components/button"
import { ProductMedia } from "types/product-media"
@@ -1243,7 +1243,7 @@ To implement this, create a storefront API Route that allows you to fetch the di
Finally, add the button as one of the product actions defined in `src/modules/products/components/product-actions/index.tsx`. These are the actions shown to the customer in the product details page:
import ProductMediaPreview from "../product-media-preview"
import { getProductMediaPreviewByVariant } from "@lib/data"
@@ -1315,7 +1315,7 @@ You can change this section to show information relevant to the product. For exa
Next, change the `ProductTabs`, `ProductInfoTab`, and `ShippingInfoTab` components defined in `src/modules/products/components/product-tabs/index.tsx` to the following:
import { useCheckout } from "@lib/context/checkout-context"
import Button from "@modules/common/components/button"
import Spinner from "@modules/common/icons/spinner"
@@ -1949,7 +1949,7 @@ When a customer purchases a digital product, the shipping form shown during chec
Finally, change the shipping details shown in the order confirmation page by replacing the content of `src/modules/order/components/shipping-details/index.tsx` with the following:
@@ -46,7 +46,7 @@ To associate these entities with the `Store` entity, you need to extend and cust
For example, to associate the `User` entity with the `Store` entity, create the file `src/models/user.ts` with the following content:
```ts title=src/models/user.ts
```ts title="src/models/user.ts"
import {
Column,
Entity,
@@ -73,7 +73,7 @@ To associate these entities with the `Store` entity, you need to extend and cust
Then, you need to extend the `UserRepository` to point to your extended entity. To do that, create the file `src/repositories/user.ts` with the following content:
```ts title=src/repositories/user.ts
```ts title="src/repositories/user.ts"
import { User } from "../models/user"
import {
dataSource,
@@ -102,7 +102,7 @@ To associate these entities with the `Store` entity, you need to extend and cust
This creates a file in the `src/migrations` directory of the format `<TIMESTAMP>_add-user-store-id.ts`. Replace the `up` and `down` methods in that file with the methods here:
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.