docs: fix code block titles (#5733)
* docs: fix code block titles * remove console * fix build error
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
"openapi-sampler": "^1.3.1",
|
||||
"openapi-types": "^12.1.3",
|
||||
"postcss": "8.4.27",
|
||||
"prism-react-renderer": "^2.0.6",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react-instantsearch": "^7.0.1",
|
||||
|
||||
@@ -12,7 +12,7 @@ In this document, you'll learn about the different ways you can configure the ad
|
||||
|
||||
The `build` command in the admin CLI allows you to manually build the admin dashboard. If you intend to use it, you should typically add it to the `package.json` of the Medusa backend:
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
// other scripts...
|
||||
@@ -29,7 +29,7 @@ You can add the following option to the `medusa-admin build` command:
|
||||
|
||||
The `develop` command in the admin CLI allows you to run the admin dashboard in development separately from the Medusa backend. If you intend to use it, you should typically add it to the `package.json` of the Medusa backend:
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
// other scripts...
|
||||
@@ -84,7 +84,7 @@ This is an advanced feature and requires knowledge of configuring webpack. If co
|
||||
|
||||
For example:
|
||||
|
||||
```js title=src/admin/webpack.config.js
|
||||
```js title="src/admin/webpack.config.js"
|
||||
import { withCustomWebpackConfig } from "@medusajs/admin"
|
||||
|
||||
export default withCustomWebpackConfig((config, webpack) => {
|
||||
|
||||
@@ -62,7 +62,7 @@ Each of the collapsible elements below hold the path to the file that you should
|
||||
<Details>
|
||||
<Summary>src/admin/types/icon-type.ts</Summary>
|
||||
|
||||
```tsx title=src/admin/types/icon-type.ts
|
||||
```tsx title="src/admin/types/icon-type.ts"
|
||||
import React from "react"
|
||||
|
||||
type IconProps = {
|
||||
@@ -80,7 +80,7 @@ Each of the collapsible elements below hold the path to the file that you should
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/shared/icons/get-started.tsx
|
||||
```tsx title="src/admin/components/shared/icons/get-started.tsx"
|
||||
import React from "react"
|
||||
import IconProps from "../../../types/icon-type"
|
||||
|
||||
@@ -115,7 +115,7 @@ Each of the collapsible elements below hold the path to the file that you should
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/shared/icons/dollar-sign-icon.tsx
|
||||
```tsx title="src/admin/components/shared/icons/dollar-sign-icon.tsx"
|
||||
import React from "react"
|
||||
import IconProps from "../../../types/icon-type"
|
||||
|
||||
@@ -162,7 +162,7 @@ Each of the collapsible elements below hold the path to the file that you should
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/shared/accordion.tsx
|
||||
```tsx title="src/admin/components/shared/accordion.tsx"
|
||||
import * as AccordionPrimitive from "@radix-ui/react-accordion"
|
||||
import React from "react"
|
||||
import { CheckCircleSolid, CircleMiniSolid } from "@medusajs/icons"
|
||||
@@ -295,7 +295,7 @@ Each of the collapsible elements below hold the path to the file that you should
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/shared/card.tsx
|
||||
```tsx title="src/admin/components/shared/card.tsx"
|
||||
import { Text, clx } from "@medusajs/ui"
|
||||
|
||||
type CardProps = {
|
||||
@@ -348,7 +348,7 @@ An [entity](../development/entities/overview.mdx) represents a table in the data
|
||||
|
||||
To create the entity, create the file `src/models/onboarding.ts` with the following content:
|
||||
|
||||
```ts title=src/models/onboarding.ts
|
||||
```ts title="src/models/onboarding.ts"
|
||||
import { BaseEntity } from "@medusajs/medusa"
|
||||
import { Column, Entity } from "typeorm"
|
||||
|
||||
@@ -367,7 +367,7 @@ export class OnboardingState extends BaseEntity {
|
||||
|
||||
Then, create the file `src/repositories/onboarding.ts` that holds the repository of the entity with the following content:
|
||||
|
||||
```ts title=src/repositories/onboarding.ts
|
||||
```ts title="src/repositories/onboarding.ts"
|
||||
import {
|
||||
dataSource,
|
||||
} from "@medusajs/medusa/dist/loaders/database"
|
||||
@@ -450,7 +450,7 @@ Start by creating the file `src/types/onboarding.ts` with the following content:
|
||||
|
||||
<!-- eslint-disable @typescript-eslint/no-empty-interface -->
|
||||
|
||||
```ts title=src/types/onboarding.ts
|
||||
```ts title="src/types/onboarding.ts"
|
||||
import { OnboardingState } from "../models/onboarding"
|
||||
|
||||
export type UpdateOnboardingStateInput = {
|
||||
@@ -472,7 +472,7 @@ Then, create the file `src/services/onboarding.ts` with the following content:
|
||||
|
||||
<!-- eslint-disable prefer-rest-params -->
|
||||
|
||||
```ts title=src/services/onboarding.ts
|
||||
```ts title="src/services/onboarding.ts"
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
import OnboardingRepository from "../repositories/onboarding"
|
||||
import { OnboardingState } from "../models/onboarding"
|
||||
@@ -540,7 +540,7 @@ The last part of this step is to create the [API Routes](../development/api-rout
|
||||
|
||||
To add these API Routes, create the file `src/api/admin/onboarding/route.ts` with the following content:
|
||||
|
||||
```ts title=src/api/admin/onboarding/route.ts
|
||||
```ts title="src/api/admin/onboarding/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -597,7 +597,7 @@ Create the file `src/admin/widgets/onboarding-flow/onboarding-flow.tsx` with the
|
||||
|
||||
<!-- eslint-disable @typescript-eslint/ban-types -->
|
||||
|
||||
```tsx title=src/admin/widgets/onboarding-flow/onboarding-flow.tsx
|
||||
```tsx title="src/admin/widgets/onboarding-flow/onboarding-flow.tsx"
|
||||
import { OrderDetailsWidgetProps, ProductDetailsWidgetProps, WidgetConfig, WidgetProps } from "@medusajs/admin"
|
||||
import { useAdminCustomPost, useAdminCustomQuery, useMedusa } from "medusa-react"
|
||||
import React, { useEffect, useState, useMemo, useCallback } from "react"
|
||||
@@ -1059,7 +1059,7 @@ const OnboardingFlow = (props: OnboardingWidgetProps) => {
|
||||
const isCurrent = currentStep === step.id
|
||||
return (
|
||||
<Accordion.Item
|
||||
title={step.title}
|
||||
title="{step.title}"
|
||||
value={step.id}
|
||||
headingSize="medium"
|
||||
active={isCurrent}
|
||||
@@ -1135,7 +1135,7 @@ Notice that as there are two types of flows, you'll be creating the components f
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/onboarding-flow/default/products/products-list.tsx
|
||||
```tsx title="src/admin/components/onboarding-flow/default/products/products-list.tsx"
|
||||
import React, { useMemo } from "react"
|
||||
import {
|
||||
useAdminCreateProduct,
|
||||
@@ -1221,7 +1221,7 @@ Notice that as there are two types of flows, you'll be creating the components f
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/onboarding-flow/default/products/product-detail.tsx
|
||||
```tsx title="src/admin/components/onboarding-flow/default/products/product-detail.tsx"
|
||||
import React, { useEffect, useMemo } from "react"
|
||||
import {
|
||||
useAdminPublishableApiKeys,
|
||||
@@ -1325,7 +1325,7 @@ Notice that as there are two types of flows, you'll be creating the components f
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/onboarding-flow/default/orders/orders-list.tsx
|
||||
```tsx title="src/admin/components/onboarding-flow/default/orders/orders-list.tsx"
|
||||
import React from "react"
|
||||
import {
|
||||
useAdminProduct,
|
||||
@@ -1420,7 +1420,7 @@ Notice that as there are two types of flows, you'll be creating the components f
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/onboarding-flow/default/orders/order-detail.tsx
|
||||
```tsx title="src/admin/components/onboarding-flow/default/orders/order-detail.tsx"
|
||||
import React from "react"
|
||||
import {
|
||||
ComputerDesktopSolid,
|
||||
@@ -1571,7 +1571,7 @@ Notice that as there are two types of flows, you'll be creating the components f
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/onboarding-flow/nextjs/products/products-list.tsx
|
||||
```tsx title="src/admin/components/onboarding-flow/nextjs/products/products-list.tsx"
|
||||
import React from "react"
|
||||
import {
|
||||
useAdminCreateProduct,
|
||||
@@ -1669,7 +1669,7 @@ Notice that as there are two types of flows, you'll be creating the components f
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/onboarding-flow/nextjs/products/product-detail.tsx
|
||||
```tsx title="src/admin/components/onboarding-flow/nextjs/products/product-detail.tsx"
|
||||
import { useAdminProduct } from "medusa-react"
|
||||
import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow"
|
||||
import { Button, Text } from "@medusajs/ui"
|
||||
@@ -1737,7 +1737,7 @@ Notice that as there are two types of flows, you'll be creating the components f
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/onboarding-flow/nextjs/orders/orders-list.tsx
|
||||
```tsx title="src/admin/components/onboarding-flow/nextjs/orders/orders-list.tsx"
|
||||
import React from "react"
|
||||
import {
|
||||
useAdminProduct,
|
||||
@@ -1817,7 +1817,7 @@ Notice that as there are two types of flows, you'll be creating the components f
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/components/onboarding-flow/nextjs/orders/order-detail.tsx
|
||||
```tsx title="src/admin/components/onboarding-flow/nextjs/orders/order-detail.tsx"
|
||||
import React from "react"
|
||||
import { CurrencyDollarSolid, NextJs, SquaresPlusSolid } from "@medusajs/icons"
|
||||
import { IconBadge, Heading, Text } from "@medusajs/ui"
|
||||
|
||||
@@ -56,7 +56,7 @@ npm install @medusajs/admin
|
||||
|
||||
In `medusa-config.js`, add the admin plugin into the array of `plugins`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ These changes may already be available in your Medusa project. They're included
|
||||
|
||||
First, update your `tsconfig.json` with the following configurations:
|
||||
|
||||
```json title=tsconfig.json
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2019",
|
||||
@@ -81,7 +81,7 @@ The addition of `"jsx": "react-jsx"` specified how should TypeScript transform J
|
||||
|
||||
Next, create the file `tsconfig.server.json` with the following content:
|
||||
|
||||
```json title=tsconfig.server.json
|
||||
```json title="tsconfig.server.json"
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
@@ -96,7 +96,7 @@ This is the configuration that will be used to transpile your custom backend cod
|
||||
|
||||
Finally, create the file `tsconfig.admin.json` with the following content:
|
||||
|
||||
```json title=tsconfig.admin.json
|
||||
```json title="tsconfig.admin.json"
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
@@ -135,7 +135,7 @@ For an admin route to be valid, it must default export a React component. There
|
||||
|
||||
For example, you can create the file `src/admin/routes/custom/page.tsx` with the following content:
|
||||
|
||||
```tsx title=src/admin/routes/custom/page.tsx
|
||||
```tsx title="src/admin/routes/custom/page.tsx"
|
||||
const CustomPage = () => {
|
||||
return (
|
||||
<div>
|
||||
@@ -217,7 +217,7 @@ The object has one property `link`, which is an object having the following prop
|
||||
|
||||
For example, you can change the content of the previous route you created to export a config object:
|
||||
|
||||
```tsx title=src/admin/routes/custom/page.tsx
|
||||
```tsx title="src/admin/routes/custom/page.tsx"
|
||||
import { RouteConfig } from "@medusajs/admin"
|
||||
import { CustomIcon } from "../../icons/custom"
|
||||
|
||||
@@ -261,7 +261,7 @@ If you're installing it in a plugin with admin customizations, make sure to incl
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/admin/routes/custom/[id]/page.tsx
|
||||
```tsx title="src/admin/routes/custom/[id]/page.tsx"
|
||||
import { useParams } from "react-router-dom"
|
||||
|
||||
const CustomPage = () => {
|
||||
@@ -285,7 +285,7 @@ If you want to use routing functionalities such as linking to another page or na
|
||||
|
||||
For example, to add a link to another page:
|
||||
|
||||
```tsx title=src/admin/routes/custom/page.tsx
|
||||
```tsx title="src/admin/routes/custom/page.tsx"
|
||||
import { Link } from "react-router-dom"
|
||||
|
||||
const CustomPage = () => {
|
||||
@@ -314,7 +314,7 @@ For example, to customize your custom route:
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/routes/custom/page.tsx
|
||||
```tsx title="src/admin/routes/custom/page.tsx"
|
||||
const CustomPage = () => {
|
||||
return (
|
||||
<div
|
||||
@@ -341,7 +341,7 @@ Make sure to also install the Medusa React package first if you’re intending t
|
||||
|
||||
For example, you can retrieve available products and display them in your route:
|
||||
|
||||
```tsx title=src/admin/routes/custom/page.tsx
|
||||
```tsx title="src/admin/routes/custom/page.tsx"
|
||||
import { useAdminProducts } from "medusa-react"
|
||||
|
||||
const CustomPage = () => {
|
||||
|
||||
@@ -36,7 +36,7 @@ These changes may already be available in your Medusa project. They're included
|
||||
|
||||
First, update your `tsconfig.json` with the following configurations:
|
||||
|
||||
```json title=tsconfig.json
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2019",
|
||||
@@ -77,7 +77,7 @@ The addition of `"jsx": "react-jsx"` specified how should TypeScript transform J
|
||||
|
||||
Next, create the file `tsconfig.server.json` with the following content:
|
||||
|
||||
```json title=tsconfig.server.json
|
||||
```json title="tsconfig.server.json"
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
@@ -92,7 +92,7 @@ This is the configuration that will be used to transpile your custom backend cod
|
||||
|
||||
Finally, create the file `tsconfig.admin.json` with the following content:
|
||||
|
||||
```json title=tsconfig.admin.json
|
||||
```json title="tsconfig.admin.json"
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
@@ -131,7 +131,7 @@ For a setting page to be valid, it must default export a React component. There
|
||||
|
||||
For example, you can create the file `src/admin/settings/custom/page.tsx` with the following content:
|
||||
|
||||
```tsx title=src/admin/settings/custom/page.tsx
|
||||
```tsx title="src/admin/settings/custom/page.tsx"
|
||||
import type { SettingConfig } from "@medusajs/admin"
|
||||
import { CustomIcon } from "../../icons/custom"
|
||||
|
||||
@@ -184,7 +184,7 @@ Every route receives props of the type `RouteProps`, which includes the `notify`
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/admin/settings/custom/page.tsx
|
||||
```tsx title="src/admin/settings/custom/page.tsx"
|
||||
import type { SettingConfig } from "@medusajs/admin"
|
||||
import type { SettingProps } from "@medusajs/admin"
|
||||
|
||||
@@ -226,7 +226,7 @@ For example, to customize the style of your custom setting page:
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/settings/custom/page.tsx
|
||||
```tsx title="src/admin/settings/custom/page.tsx"
|
||||
import type { SettingConfig } from "@medusajs/admin"
|
||||
|
||||
const CustomSettingPage = () => {
|
||||
@@ -269,7 +269,7 @@ If you're installing it in a plugin with admin customizations, make sure to incl
|
||||
|
||||
For example, to add a link to another page:
|
||||
|
||||
```tsx title=src/admin/settings/custom/page.tsx
|
||||
```tsx title="src/admin/settings/custom/page.tsx"
|
||||
import type { SettingConfig } from "@medusajs/admin"
|
||||
import { Link } from "react-router-dom"
|
||||
|
||||
@@ -310,7 +310,7 @@ Make sure to also install the Medusa React package first if you’re intending t
|
||||
|
||||
For example, you can retrieve available products and display them in your route:
|
||||
|
||||
```tsx title=src/admin/settings/custom/page.tsx
|
||||
```tsx title="src/admin/settings/custom/page.tsx"
|
||||
import type { SettingConfig } from "@medusajs/admin"
|
||||
import { useAdminProducts } from "medusa-react"
|
||||
|
||||
|
||||
@@ -956,7 +956,7 @@ These changes may already be available in your Medusa project. They're included
|
||||
|
||||
First, update your `tsconfig.json` with the following configurations:
|
||||
|
||||
```json title=tsconfig.json
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2019",
|
||||
@@ -997,7 +997,7 @@ The addition of `"jsx": "react-jsx"` specified how should TypeScript transform J
|
||||
|
||||
Next, create the file `tsconfig.server.json` with the following content:
|
||||
|
||||
```json title=tsconfig.server.json
|
||||
```json title="tsconfig.server.json"
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
@@ -1012,7 +1012,7 @@ This is the configuration that will be used to transpile your custom backend cod
|
||||
|
||||
Finally, create the file `tsconfig.admin.json` with the following content:
|
||||
|
||||
```json title=tsconfig.admin.json
|
||||
```json title="tsconfig.admin.json"
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
@@ -1029,7 +1029,7 @@ This is the configuration that will be used when transpiling your admin code.
|
||||
|
||||
You can optionally update the following scripts in `package.json` to make your development process easier:
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
{
|
||||
// ...
|
||||
"scripts": {
|
||||
@@ -1060,7 +1060,7 @@ To create a new admin widget, start by creating the folder `src/admin/widgets`.
|
||||
|
||||
Then, create the file `src/admin/widgets/product-widget.tsx` with the following content:
|
||||
|
||||
```tsx title=src/admin/widgets/product-widget.tsx
|
||||
```tsx title="src/admin/widgets/product-widget.tsx"
|
||||
import type { WidgetConfig } from "@medusajs/admin"
|
||||
|
||||
const ProductWidget = () => {
|
||||
@@ -1111,7 +1111,7 @@ For example, you can modify the widget you created to show the title of the prod
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/widgets/product-widget.tsx
|
||||
```tsx title="src/admin/widgets/product-widget.tsx"
|
||||
import type {
|
||||
WidgetConfig,
|
||||
ProductDetailsWidgetProps,
|
||||
@@ -1151,7 +1151,7 @@ For example, you can update the widget you created earlier to use Tailwind CSS c
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/widgets/product-widget.tsx
|
||||
```tsx title="src/admin/widgets/product-widget.tsx"
|
||||
import type {
|
||||
WidgetConfig,
|
||||
} from "@medusajs/admin"
|
||||
@@ -1194,7 +1194,7 @@ For example:
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/widgets/product-widget.tsx
|
||||
```tsx title="src/admin/widgets/product-widget.tsx"
|
||||
import type { WidgetConfig } from "@medusajs/admin"
|
||||
import { Link } from "react-router-dom"
|
||||
|
||||
@@ -1235,7 +1235,7 @@ For example, you can modify the widget you created to retrieve the tags of a pro
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/admin/widgets/product-widget.tsx
|
||||
```tsx title="src/admin/widgets/product-widget.tsx"
|
||||
import type { ProductDetailsWidgetProps, WidgetConfig } from "@medusajs/admin"
|
||||
import { useAdminProductTags } from "medusa-react"
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ Where `<LANGUAGE>` is your language name. For example, `feat/translate-da`.
|
||||
|
||||
7\. In `packages/admin-ui/ui/src/i18n/index.ts`, add the new language to the `supportedLanguages` array as an object. The object accepts two properties: `locale` for the ISO 2 character code, and `name` for the name of the language. The name of the language should be the translated name, not the English name. For example:
|
||||
|
||||
```ts title=packages/admin-ui/ui/src/i18n/index.ts
|
||||
```ts title="packages/admin-ui/ui/src/i18n/index.ts"
|
||||
export const supportedLanguages = [
|
||||
// other languages...
|
||||
{
|
||||
|
||||
@@ -120,7 +120,7 @@ To add an icon to the sidebar item, start by checking if the icon is already exp
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=www/docs/src/theme/Icon/Bolt/index.tsx
|
||||
```tsx title="www/docs/src/theme/Icon/Bolt/index.tsx"
|
||||
import React from "react"
|
||||
import { IconProps } from "@medusajs/icons/dist/types"
|
||||
|
||||
@@ -148,7 +148,7 @@ Make sure to set the `stroke` or `fill` of the icon to `currentColor` as shown i
|
||||
|
||||
If you added a new icon, add it in the exported object in the file `www/apps/docs/src/theme/Icon/index.ts`, where the property is the kebab-case version of the icon's name, and the value being the component you created. Make sure to add it in the correct alphabetical position as well. For example:
|
||||
|
||||
```ts title=www/docs/src/theme/Icon/index.ts
|
||||
```ts title="www/docs/src/theme/Icon/index.ts"
|
||||
import IconBolt from "./Bolt"
|
||||
import IconBoltSolid from "./BoltSolid"
|
||||
// other imports
|
||||
@@ -163,7 +163,7 @@ export default {
|
||||
|
||||
Finally, you can add the icon to the sidebar item by adding a `sidebar_icon` property to the `customProps` property and setting its value to the kebab-cased version of the icon's name. For example:
|
||||
|
||||
```js title=www/docs/sidebars.js
|
||||
```js title="www/docs/sidebars.js"
|
||||
module.exports = {
|
||||
// other sidebars
|
||||
homepage: [
|
||||
@@ -184,7 +184,7 @@ There are different sidebar item types used in the documentation:
|
||||
|
||||
- Homepage Items: If a sidebar item is shown under the `homepage` sidebar, you should set the `className` property of the item to `homepage-sidebar-item`. You can use this with other sidebar item types. For example:
|
||||
|
||||
```js title=www/docs/sidebars.js
|
||||
```js title="www/docs/sidebars.js"
|
||||
module.exports = {
|
||||
// other sidebars
|
||||
homepage: [
|
||||
@@ -200,7 +200,7 @@ There are different sidebar item types used in the documentation:
|
||||
|
||||
- Sidebar Title: This item is used as a title to the sidebar, typically added at the top of the sidebar. You typically would also use an icon with it. To use this item, add a `sidebar_is_title` property to the `customProps` object of the item with its value being `true`. For example:
|
||||
|
||||
```js title=www/docs/sidebars.js
|
||||
```js title="www/docs/sidebars.js"
|
||||
module.exports = {
|
||||
// other sidebars
|
||||
modules: [
|
||||
@@ -221,7 +221,7 @@ There are different sidebar item types used in the documentation:
|
||||
|
||||
- Back Item: This item is used to show a back button, typically at the top of the sidebar. To use this item, add the `sidebar_is_back_link` property to the `customProps` object of the item, with its value set to true. Also, add the `sidebar_icon` property to the `customProps` object with its value set to `back-arrow`. For example:
|
||||
|
||||
```js title=www/docs/sidebars.js
|
||||
```js title="www/docs/sidebars.js"
|
||||
module.exports = {
|
||||
// other sidebars
|
||||
core: [
|
||||
@@ -242,7 +242,7 @@ There are different sidebar item types used in the documentation:
|
||||
|
||||
- Group Divider Item: This item is used if a sidebar item does not link to any document and is only used to separate between sidebar sections. The item must be of type `html`, and its `value` property holds the text that should be shown in the divider. You must also add in the `customProps` object of the item the property `sidebar_is_group_divider` with its value being `true`. For example:
|
||||
|
||||
```js title=www/docs/sidebars.js
|
||||
```js title="www/docs/sidebars.js"
|
||||
module.exports = {
|
||||
// other sidebars
|
||||
homepage: [
|
||||
@@ -262,7 +262,7 @@ There are different sidebar item types used in the documentation:
|
||||
|
||||
- Group Headline Item: This item is used if a sidebar item does not link to any document and is only used to indicate the beginning of a new section or group in the sidebar. To use this item, set the `type` of the item to `category`, and add the `sidebar_is_group_headline` property to the `customProps` object of the item, with its value set to `true`. For example:
|
||||
|
||||
```js title=www/docs/sidebars.js
|
||||
```js title="www/docs/sidebars.js"
|
||||
module.exports = {
|
||||
// other sidebars
|
||||
modules: [
|
||||
@@ -285,7 +285,7 @@ There are different sidebar item types used in the documentation:
|
||||
|
||||
- Soon Item: This item is used to indicate that a certain guide will be added soon, but it does not actually link to any document. To use this item, set the `type` of the item to `link`, its `href` property to `#`, and add to the `customProps` object the property `sidebar_is_soon` with its value set to `true`. For example:
|
||||
|
||||
```js title=www/docs/sidebars.js
|
||||
```js title="www/docs/sidebars.js"
|
||||
module.exports = {
|
||||
// other sidebars
|
||||
modules: [
|
||||
@@ -392,7 +392,7 @@ For example:
|
||||
To add a title to a code block without tabs:
|
||||
|
||||
~~~md
|
||||
```js title=src/index.ts
|
||||
```js title="src/index.ts"
|
||||
console.log("hello")
|
||||
```
|
||||
~~~
|
||||
|
||||
@@ -66,7 +66,7 @@ const DATABASE_URL =
|
||||
|
||||
In addition, you must add to `projectConfig` in the exported object a new property `database_extra`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
// ...
|
||||
@@ -77,7 +77,7 @@ module.exports = {
|
||||
|
||||
Also, if you're planning on using scheduled jobs, you need to set the `redis_url` configurations:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
// ...
|
||||
|
||||
@@ -25,7 +25,7 @@ If your hosting provider supports that, create a GitHub repository and push your
|
||||
|
||||
Make sure the `start` script in your `package.json` runs migrations, the `build` command, and the `medusa start` command:
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
"start": "npm run build && medusa migrations run && medusa start"
|
||||
```
|
||||
|
||||
@@ -35,7 +35,7 @@ Make sure the `start` script in your `package.json` runs migrations, the `build`
|
||||
|
||||
In production, it’s recommended to set the [database_extra option](../../development/backend/configurations.md#database_extra) in `medusa-config.js` to disable the `ssl.rejectUnauthorized` option:
|
||||
|
||||
```jsx title=medusa-config.js
|
||||
```jsx title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
// ...
|
||||
|
||||
@@ -48,7 +48,7 @@ You can learn more about Middlewares and their capabilities in [Express’s docu
|
||||
|
||||
Here's an example of a middleware:
|
||||
|
||||
```ts title=src/api/middlewares/custom-middleware.ts
|
||||
```ts title="src/api/middlewares/custom-middleware.ts"
|
||||
export function customMiddleware(req, res, next) {
|
||||
// TODO perform an action
|
||||
|
||||
@@ -66,7 +66,7 @@ The examples used here don't apply Cross-Origin Resource Origin (CORS) options f
|
||||
|
||||
:::
|
||||
|
||||
```ts title=src/api/index.ts
|
||||
```ts title="src/api/index.ts"
|
||||
import { Router } from "express"
|
||||
import {
|
||||
customMiddleware,
|
||||
@@ -118,7 +118,7 @@ If you want to register a logged-in user and access it in your resources, you ca
|
||||
|
||||
To register a new resource in the dependency container, use the `req.scope.register` method:
|
||||
|
||||
```ts title=src/api/middlewares/custom-middleware.ts
|
||||
```ts title="src/api/middlewares/custom-middleware.ts"
|
||||
export function customMiddleware(req, res, next) {
|
||||
// TODO perform an action
|
||||
|
||||
@@ -136,7 +136,7 @@ You can then load this new resource within other resources. For example, to load
|
||||
|
||||
<!-- eslint-disable prefer-rest-params -->
|
||||
|
||||
```ts title=src/services/custom-service.ts
|
||||
```ts title="src/services/custom-service.ts"
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
|
||||
class CustomService extends TransactionBaseService {
|
||||
|
||||
@@ -18,7 +18,7 @@ v1.17.2 of `@medusajs/medusa` introduced a new approach to creating middlewares
|
||||
|
||||
## Basic Implementation
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import type { MiddlewaresConfig } from "@medusajs/medusa"
|
||||
import type {
|
||||
MedusaNextFunction,
|
||||
@@ -99,7 +99,7 @@ The `resolve`'s value is a function that returns the resource to be registered i
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import type { MiddlewaresConfig } from "@medusajs/medusa"
|
||||
import type {
|
||||
MedusaNextFunction,
|
||||
@@ -134,7 +134,7 @@ You can then load this new resource within other resources. For example, to load
|
||||
|
||||
<!-- eslint-disable prefer-rest-params -->
|
||||
|
||||
```ts title=src/services/custom-service.ts
|
||||
```ts title="src/services/custom-service.ts"
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
|
||||
class CustomService extends TransactionBaseService {
|
||||
|
||||
@@ -19,7 +19,7 @@ Following v1.17.2 of `@medusajs/medusa`, it's highly recommended to use the [API
|
||||
|
||||
To create a new endpoint, start by creating a new file in `src/api` called `index.ts`. At its basic format, `index.ts` should look something like this:
|
||||
|
||||
```ts title=src/api/index.ts
|
||||
```ts title="src/api/index.ts"
|
||||
import { Router } from "express"
|
||||
|
||||
export default (rootDirectory, options) => {
|
||||
@@ -62,7 +62,7 @@ Instead of returning an Express router in the function, you can return an array
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/index.ts
|
||||
```ts title="src/api/index.ts"
|
||||
import { Router } from "express"
|
||||
|
||||
export default (rootDirectory, options) => {
|
||||
@@ -199,7 +199,7 @@ If you want to accept request body parameters, you need to pass express middlewa
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/index.ts
|
||||
```ts title="src/api/index.ts"
|
||||
import bodyParser from "body-parser"
|
||||
import express, { Router } from "express"
|
||||
|
||||
@@ -356,7 +356,7 @@ The function returns an object with the following properties:
|
||||
|
||||
Here's an example of retrieving the configurations within an endpoint using `getConfigFile`:
|
||||
|
||||
```ts title=src/api/index.ts
|
||||
```ts title="src/api/index.ts"
|
||||
import { Router } from "express"
|
||||
import { ConfigModule } from "@medusajs/medusa"
|
||||
import { getConfigFile } from "medusa-core-utils"
|
||||
@@ -382,7 +382,7 @@ Notice that `getConfigFile` is a generic function. So, if you're using TypeScrip
|
||||
|
||||
If you're accessing custom configurations, you'll need to create a new type that defines these configurations. For example:
|
||||
|
||||
```ts title=src/api/index.ts
|
||||
```ts title="src/api/index.ts"
|
||||
import { Router } from "express"
|
||||
import { ConfigModule } from "@medusajs/medusa"
|
||||
import { getConfigFile } from "medusa-core-utils"
|
||||
@@ -426,7 +426,7 @@ Code snippets are taken from the [full example available at the end of this docu
|
||||
|
||||
To handle errors using Medusa's middlewares, first, import the `errorHandler` middleware from `@medusajs/medusa` and apply it on your routers. Make sure it's applied after all other middlewares and routes:
|
||||
|
||||
```ts title=src/api/index.ts
|
||||
```ts title="src/api/index.ts"
|
||||
import express, { Router } from "express"
|
||||
import adminRoutes from "./admin"
|
||||
import storeRoutes from "./store"
|
||||
@@ -449,7 +449,7 @@ export default (rootDirectory, options) => {
|
||||
|
||||
Then, wrap the function handler of every route with the `wrapHandler` middleware imported from `@medusajs/medusa`. For example:
|
||||
|
||||
```ts title=src/api/admin.ts
|
||||
```ts title="src/api/admin.ts"
|
||||
import { wrapHandler } from "@medusajs/medusa"
|
||||
|
||||
// ...
|
||||
@@ -477,7 +477,7 @@ Alternatively, you can define the endpoints in different files, and import and u
|
||||
|
||||
<!-- eslint-disable @typescript-eslint/no-var-requires -->
|
||||
|
||||
```ts title=src/api/admin.ts
|
||||
```ts title="src/api/admin.ts"
|
||||
import { wrapHandler } from "@medusajs/medusa"
|
||||
|
||||
// ...
|
||||
|
||||
@@ -17,7 +17,7 @@ v1.17.2 of `@medusajs/medusa` introduced API Routes to replace Express endpoints
|
||||
|
||||
## Basic Implementation
|
||||
|
||||
```ts title=src/api/store/custom/route.ts
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -91,7 +91,7 @@ You can access a path parameter's value in method handlers using the `MedusaRequ
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/store/custom/[id]/route.ts
|
||||
```ts title="src/api/store/custom/[id]/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -119,7 +119,7 @@ The `cors` middleware, which enables Cross-Origin Resource Sharing (CORS), is au
|
||||
|
||||
To add CORS configurations to custom API routes under other path prefixes, or override the CORS configurations added by default, define a [middleware](./add-middleware.mdx) on your API routes and pass it the `cors` middleware. For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import type {
|
||||
MiddlewaresConfig,
|
||||
} from "@medusajs/medusa"
|
||||
@@ -146,7 +146,7 @@ To disable the `cors` middleware for an API Route, export a `CORS` variable in t
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/store/custom/route.ts
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -174,7 +174,7 @@ Each of the `body`'s keys are a name of the request body parameters, and its val
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/store/custom/route.ts
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -194,7 +194,7 @@ If you want to parse other content types, such as `application/x-www-form-urlenc
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import type {
|
||||
MiddlewaresConfig,
|
||||
} from "@medusajs/medusa"
|
||||
@@ -224,7 +224,7 @@ You can opt out of the default body parser by setting the `bodyParser` property
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import { MiddlewaresConfig } from "@medusajs/medusa"
|
||||
import { raw } from "body-parser"
|
||||
|
||||
@@ -243,7 +243,7 @@ You can also disable the default `json` body parser for specific HTTP methods us
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import { MiddlewaresConfig } from "@medusajs/medusa"
|
||||
import { raw } from "body-parser"
|
||||
|
||||
@@ -269,7 +269,7 @@ If you expect the request body of an API Route to be larger than the default, yo
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import { MiddlewaresConfig } from "@medusajs/medusa"
|
||||
|
||||
export const config: MiddlewaresConfig = {
|
||||
@@ -294,7 +294,7 @@ By default, API routes prefixed by `/store` don't require customer authenticatio
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/store/custom/route.ts
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import { CustomerService } from "@medusajs/medusa"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
@@ -327,7 +327,7 @@ API Routes prefixed by `/store/me`, on the other hand, require customer authenti
|
||||
|
||||
If you want to disable authentication requirement on your custom API Route prefixed with `/store/me`, export an `AUTHENTICATE` variable in the route file with its value set to `false`. For example:
|
||||
|
||||
```ts title=src/api/store/me/custom/route.ts
|
||||
```ts title="src/api/store/me/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -357,7 +357,7 @@ By default, all API Routes prefixed by `/admin` require admin user authenticatio
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/admin/custom/route.ts
|
||||
```ts title="src/api/admin/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -384,7 +384,7 @@ To disable authentication requirement on an admin API Route, export an `AUTHENTI
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/admin/custom/route.ts
|
||||
```ts title="src/api/admin/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -418,7 +418,7 @@ To protect API routes that aren't prefixed with `/store` or `/admin`, you can us
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import {
|
||||
authenticate,
|
||||
requireCustomerAuthentication,
|
||||
@@ -447,7 +447,7 @@ You can access the configurations exported in `medusa-config.js`, including your
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/store/custom/route.ts
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -562,7 +562,7 @@ To override the default error handler, pass the `errorHandler` property to the [
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import { MiddlewaresConfig } from "@medusajs/medusa"
|
||||
|
||||
export const config: MiddlewaresConfig = {
|
||||
@@ -578,7 +578,7 @@ To disable the default error handler, set the `errorHandler` property of the [ex
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import { MiddlewaresConfig } from "@medusajs/medusa"
|
||||
|
||||
export const config: MiddlewaresConfig = {
|
||||
@@ -592,7 +592,7 @@ To ensure that errors are still returned in the response when the default error
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -624,7 +624,7 @@ Posts are represented by a custom entity not covered in this guide. You can refe
|
||||
|
||||
:::
|
||||
|
||||
```ts title=src/api/store/posts/route.ts
|
||||
```ts title="src/api/store/posts/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -659,7 +659,7 @@ Notice that to retrieve an instance of the repository, you need to retrieve firs
|
||||
|
||||
:::
|
||||
|
||||
```ts title=src/api/store/posts/route.ts
|
||||
```ts title="src/api/store/posts/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -22,7 +22,7 @@ Learn more about [middlewares in its guide](./add-middleware.mdx).
|
||||
|
||||
Create the file `src/api/middlewares.ts` with the following content:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import type {
|
||||
MiddlewaresConfig,
|
||||
User,
|
||||
|
||||
@@ -40,7 +40,7 @@ In the file you created, which in this case is `src/api/index.ts`, add the follo
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```ts title=src/api/index.ts
|
||||
```ts title="src/api/index.ts"
|
||||
import { registerOverriddenValidators } from "@medusajs/medusa"
|
||||
import {
|
||||
AdminPostProductsReq as MedusaAdminPostProductsReq,
|
||||
|
||||
@@ -27,7 +27,7 @@ The configurations for your Medusa backend are in `medusa-config.js` located in
|
||||
|
||||
For example:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig,
|
||||
plugins,
|
||||
@@ -76,7 +76,7 @@ ADMIN_CORS=/http:\/\/*/
|
||||
|
||||
Typically, the value of these configurations would be set in an environment variable and referenced in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
admin_cors: process.env.ADMIN_CORS,
|
||||
@@ -89,7 +89,7 @@ module.exports = {
|
||||
|
||||
If you’re adding the value directly within `medusa-config.js`, make sure to add an extra escaping `/` for every backslash in the pattern. For example:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
admin_cors: "/http:\\/\\/localhost:700\\d+$/",
|
||||
@@ -108,7 +108,7 @@ In a development environment, if this option is not set the default secret is `s
|
||||
|
||||
Typically, the value of this configuration would be set in an environment variable and referenced in `medusa-config.js`.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
cookie_secret: process.env.COOKIE_SECRET,
|
||||
@@ -131,7 +131,7 @@ Its value is an object that has the following properties:
|
||||
|
||||
If you enable HTTP compression and you want to disable it for specific API Routes, you can pass in the request header `"x-no-compression": true`.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
http_compression: {
|
||||
@@ -154,7 +154,7 @@ In a development environment, if this option is not set the default secret is `s
|
||||
|
||||
Typically, the value of this configuration would be set in an environment variable and referenced in `medusa-config.js`.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
jwt_secret: process.env.JWT_SECRET,
|
||||
@@ -170,7 +170,7 @@ The name of the database to connect to. If provided in `database_url`, then it
|
||||
|
||||
Make sure to create the PostgreSQL database before using it. You can check how to create a database in [PostgreSQL's documentation](https://www.postgresql.org/docs/current/sql-createdatabase.html).
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
database_database: "medusa-store",
|
||||
@@ -186,7 +186,7 @@ An object that includes additional configurations to pass to the database connec
|
||||
|
||||
This is useful for production databases, which can be supported by setting the `rejectUnauthorized` attribute of `ssl` object to `false`. During development, it’s recommended not to pass this option.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
database_extra:
|
||||
@@ -207,7 +207,7 @@ This configuration specifies what messages to log. Its value can be one of the f
|
||||
- The string value `all` that indicates all types of messages should be logged.
|
||||
- An array of log-level strings to indicate which type of messages to show in the logs. The strings can be `query`, `schema`, `error`, `warn`, `info`, `log`, or `migration`. Refer to [Typeorm’s documentation](https://typeorm.io/logging#logging-options) for more details on what each of these values means.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
database_logging: [
|
||||
@@ -223,7 +223,7 @@ module.exports = {
|
||||
|
||||
A string indicating the database schema to connect to. This is not necessary to provide if you’re using the default schema, which is `public`.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
database_schema: "custom",
|
||||
@@ -237,7 +237,7 @@ module.exports = {
|
||||
|
||||
A string indicating the type of database to connect to. At the moment, only `postgres` is accepted, which is also the default value.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
database_type: "postgres",
|
||||
@@ -273,7 +273,7 @@ DATABASE_URL=postgres://postgres@localhost/medusa-store
|
||||
|
||||
You can learn more about the connection URL format in [PostgreSQL’s documentation](https://www.postgresql.org/docs/current/libpq-connect.html).
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
database_url: process.env.DATABASE_URL,
|
||||
@@ -303,7 +303,7 @@ For a local Redis installation, the connection URL should be `redis://localhost:
|
||||
|
||||
Typically, the value would be added as an environment variable and referenced in `medusa-config.js`.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
redis_url: process.env.REDIS_URL,
|
||||
@@ -317,7 +317,7 @@ module.exports = {
|
||||
|
||||
The prefix set on all keys stored in Redis. The default value is `sess:`. If this configuration option is provided, it is prepended to `sess:`.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
redis_prefix: "medusa:",
|
||||
@@ -331,7 +331,7 @@ module.exports = {
|
||||
|
||||
An object of options to pass ioredis. You can refer to [ioredis’s RedisOptions documentation](https://redis.github.io/ioredis/index.html#RedisOptions) for the list of available options.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
redis_options: {
|
||||
@@ -354,7 +354,7 @@ An object of options to pass to `express-session`. The object can have the follo
|
||||
- `secret`: A string that indicates the secret to sign the session ID cookie. By default, the value of [cookie_secret](#cookie_secret) will be used. Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#secret) for details.
|
||||
- `ttl`: A number is used when calculating the `Expires` `Set-Cookie` attribute of cookies. By default, it’ll be `10 * 60 * 60 * 1000`. Refer to [express-session’s documentation](https://www.npmjs.com/package/express-session#cookiemaxage) for details.
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
session_options: {
|
||||
@@ -383,7 +383,7 @@ The items in the array can either be:
|
||||
|
||||
For example:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
plugins: [
|
||||
`medusa-my-plugin-1`,
|
||||
@@ -422,7 +422,7 @@ The keys of the `modules` configuration object refer to the type of module. Its
|
||||
|
||||
For example:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
modules: {
|
||||
eventBus: {
|
||||
@@ -457,7 +457,7 @@ You can find available feature flags and their key name [here](https://github.co
|
||||
|
||||
For example:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
featureFlags: {
|
||||
product_categories: true,
|
||||
|
||||
@@ -46,7 +46,7 @@ Batch job strategies must extend the abstract class `AbstractBatchJobStrategy` a
|
||||
|
||||
Add the following content to the file you created:
|
||||
|
||||
```ts title=src/strategies/publish.ts
|
||||
```ts title="src/strategies/publish.ts"
|
||||
import {
|
||||
AbstractBatchJobStrategy,
|
||||
BatchJobService,
|
||||
|
||||
@@ -41,7 +41,7 @@ The batch job strategy class must extend the `AbstractBatchJobStrategy` class wh
|
||||
|
||||
For example, you can define the following class in the file you created:
|
||||
|
||||
```ts title=src/strategies/import.ts
|
||||
```ts title="src/strategies/import.ts"
|
||||
import {
|
||||
AbstractBatchJobStrategy,
|
||||
BatchJobService,
|
||||
|
||||
+7
-7
@@ -34,7 +34,7 @@ Create the file `src/services/memcached-cache.ts` which will hold your cache ser
|
||||
|
||||
Add the following content to the file:
|
||||
|
||||
```ts title=src/services/memcached-cache.ts
|
||||
```ts title="src/services/memcached-cache.ts"
|
||||
import { ICacheService } from "@medusajs/types"
|
||||
|
||||
class MemcachedCacheService implements ICacheService {
|
||||
@@ -70,7 +70,7 @@ The `constructor` method of a service allows you to prepare any third-party clie
|
||||
|
||||
Here’s an example of how you can use the `constructor` to create a memcached instance and save the module’s options:
|
||||
|
||||
```ts title=src/services/memcached-cache.ts
|
||||
```ts title="src/services/memcached-cache.ts"
|
||||
import { ICacheService } from "@medusajs/types"
|
||||
import Memcached from "memcached"
|
||||
|
||||
@@ -117,7 +117,7 @@ The `get` method allows you to retrieve the value of a cached item based on its
|
||||
|
||||
Here’s an example implementation of this method for a Memcached service:
|
||||
|
||||
```ts title=src/services/memcached-cache.ts
|
||||
```ts title="src/services/memcached-cache.ts"
|
||||
class MemcachedCacheService implements ICacheService {
|
||||
// ...
|
||||
async get<T>(cacheKey: string): Promise<T | null> {
|
||||
@@ -148,7 +148,7 @@ The `set` method is used to set an item in the cache. It accepts three parameter
|
||||
|
||||
Here’s an example of an implementation of this method for a Memcached service:
|
||||
|
||||
```ts title=src/services/memcached-cache.ts
|
||||
```ts title="src/services/memcached-cache.ts"
|
||||
class MemcachedCacheService implements ICacheService {
|
||||
// ...
|
||||
async set(
|
||||
@@ -178,7 +178,7 @@ The method accepts a string as a first parameter, which is the key of the item t
|
||||
|
||||
Here’s an example of an implementation of this method for a Memcached service:
|
||||
|
||||
```ts title=src/services/memcached-cache.ts
|
||||
```ts title="src/services/memcached-cache.ts"
|
||||
class MemcachedCacheService implements ICacheService {
|
||||
// ...
|
||||
async invalidate(key: string): Promise<void> {
|
||||
@@ -203,7 +203,7 @@ After implementing the cache service, you must export it so that the Medusa back
|
||||
|
||||
Create the file `src/index.ts` with the following content:
|
||||
|
||||
```ts title=src/index.ts
|
||||
```ts title="src/index.ts"
|
||||
import { ModuleExports } from "@medusajs/modules-sdk"
|
||||
|
||||
import {
|
||||
@@ -231,7 +231,7 @@ You can test your module in the Medusa backend by referencing it in the configur
|
||||
|
||||
To do that, add the module to the exported configuration in `medusa-config.js` as follows:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
|
||||
@@ -40,7 +40,7 @@ npm install @medusajs/cache-inmemory
|
||||
|
||||
In `medusa-config.js`, add the following to the exported object:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
|
||||
@@ -52,7 +52,7 @@ Where `<YOUR_REDIS_URL>` is a connection URL to your Redis instance.
|
||||
|
||||
In `medusa-config.js`, add the following to the exported object:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
|
||||
@@ -20,7 +20,7 @@ Entities can only be placed in the top level of the `src/models` directory. So,
|
||||
|
||||
:::
|
||||
|
||||
```ts title=src/models/post.ts
|
||||
```ts title="src/models/post.ts"
|
||||
import {
|
||||
BeforeInsert,
|
||||
Column,
|
||||
|
||||
@@ -33,7 +33,7 @@ In the file you created, you can import the entity you’re extending from the c
|
||||
|
||||
Here’s an example of extending the Product entity:
|
||||
|
||||
```ts title=src/models/product.ts
|
||||
```ts title="src/models/product.ts"
|
||||
import { Column, Entity } from "typeorm"
|
||||
import {
|
||||
// alias the core entity to not cause a naming conflict
|
||||
@@ -55,7 +55,7 @@ If you’re using JavaScript instead of TypeScript in your implementation, you c
|
||||
|
||||
To ensure that TypeScript is aware of your extended entity and affects the typing of the Medusa package itself, create the file `src/index.d.ts` with the following content:
|
||||
|
||||
```ts title=src/index.d.ts
|
||||
```ts title="src/index.d.ts"
|
||||
export declare module "@medusajs/medusa/dist/models/product" {
|
||||
declare interface Product {
|
||||
customAttribute: string;
|
||||
@@ -81,7 +81,7 @@ You can learn how to create or generate a migration in [this documentation](./mi
|
||||
|
||||
Here’s an example of a migration of the entity extended in this guide:
|
||||
|
||||
```ts title=src/migration/1680013376180-changeProduct.ts
|
||||
```ts title="src/migration/1680013376180-changeProduct.ts"
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
class changeProduct1680013376180 implements MigrationInterface {
|
||||
@@ -140,7 +140,7 @@ To change that and ensure your custom attribute is returned in your request, you
|
||||
|
||||
For example, if you added a custom attribute in the `Product` entity and you want to ensure it's returned in all the product's store API Routes (API Routes under the prefix `/store/products`), you can create a file under the `src/loaders` directory in your Medusa backend with the following content:
|
||||
|
||||
```ts title=src/loaders/extend-product-fields.ts
|
||||
```ts title="src/loaders/extend-product-fields.ts"
|
||||
export default async function () {
|
||||
const imports = (await import(
|
||||
"@medusajs/medusa/dist/api/routes/store/products/index"
|
||||
|
||||
@@ -39,7 +39,7 @@ A data source is Typeorm’s connection settings that allows you to connect to y
|
||||
|
||||
Here’s an example of the implementation of the extended Product repository:
|
||||
|
||||
```ts title=src/repositories/product.ts
|
||||
```ts title="src/repositories/product.ts"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import {
|
||||
dataSource,
|
||||
@@ -87,7 +87,7 @@ You can now use your extended repository in other resources such as services or
|
||||
|
||||
Here’s an example of using it in an API Route:
|
||||
|
||||
```ts title=src/api/store/custom/route.ts
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -22,7 +22,7 @@ If you haven't created a custom repository, you can access the default repositor
|
||||
|
||||
For example, to retrieve the default repository of an entity in a service:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import { Post } from "../models/post"
|
||||
|
||||
class PostService extends TransactionBaseService {
|
||||
@@ -41,7 +41,7 @@ class PostService extends TransactionBaseService {
|
||||
|
||||
Another example is retrieving the default repository of an entity in an API Route:
|
||||
|
||||
```ts title=src/api/store/custom/route.ts
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -110,7 +110,7 @@ To access a custom repository within an API Route, use the `MedusaRequest` objec
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/store/custom/route.ts
|
||||
```ts title="src/store/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -141,7 +141,7 @@ As custom repositories are registered in the [dependency container](../fundament
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import { PostRepository } from "../repositories/post"
|
||||
|
||||
class PostService extends TransactionBaseService {
|
||||
@@ -173,7 +173,7 @@ A subscriber handler function can resolve a repository using the `container` pro
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/subscribers/post-handler.ts
|
||||
```ts title="src/subscribers/post-handler.ts"
|
||||
import {
|
||||
type SubscriberArgs,
|
||||
} from "@medusajs/medusa"
|
||||
|
||||
@@ -29,7 +29,7 @@ Create the file `services/event-bus-custom.ts` which will hold your event bus se
|
||||
|
||||
Add the following content to the file:
|
||||
|
||||
```ts title=services/event-bus-custom.ts
|
||||
```ts title="services/event-bus-custom.ts"
|
||||
import { EmitData, EventBusTypes } from "@medusajs/types"
|
||||
import { AbstractEventBusModuleService } from "@medusajs/utils"
|
||||
|
||||
@@ -81,7 +81,7 @@ Here’s an example of how you can use the `constructor` to store the options of
|
||||
|
||||
<!-- eslint-disable prefer-rest-params -->
|
||||
|
||||
```ts title=services/event-bus-custom.ts
|
||||
```ts title="services/event-bus-custom.ts"
|
||||
class CustomEventBus extends AbstractEventBusModuleService {
|
||||
protected readonly moduleOptions: Record<string, any>
|
||||
|
||||
@@ -109,7 +109,7 @@ The `emit` method has two different signatures:
|
||||
|
||||
The `options` parameter depends on the event bus integration. For example, the Redis event bus accepts the following options:
|
||||
|
||||
```ts title=services/event-bus-custom.ts
|
||||
```ts title="services/event-bus-custom.ts"
|
||||
type JobData<T> = {
|
||||
eventName: string
|
||||
data: T
|
||||
@@ -119,7 +119,7 @@ type JobData<T> = {
|
||||
|
||||
You can implement your method in a way that supports both signatures by checking the type of the first input. For example:
|
||||
|
||||
```ts title=services/event-bus-custom.ts
|
||||
```ts title="services/event-bus-custom.ts"
|
||||
class CustomEventBus extends AbstractEventBusModuleService {
|
||||
// ...
|
||||
async emit<T>(
|
||||
@@ -154,7 +154,7 @@ The `subscribe` method accepts three parameters:
|
||||
|
||||
The implementation of this method depends on the service you’re using for the event bus:
|
||||
|
||||
```ts title=services/event-bus-custom.ts
|
||||
```ts title="services/event-bus-custom.ts"
|
||||
class CustomEventBus extends AbstractEventBusModuleService {
|
||||
// ...
|
||||
subscribe(
|
||||
@@ -180,7 +180,7 @@ The `unsubscribe` method accepts three parameters:
|
||||
|
||||
The implementation of this method depends on the service you’re using for the event bus:
|
||||
|
||||
```ts title=services/event-bus-custom.ts
|
||||
```ts title="services/event-bus-custom.ts"
|
||||
class CustomEventBus extends AbstractEventBusModuleService {
|
||||
// ...
|
||||
unsubscribe(
|
||||
@@ -200,7 +200,7 @@ After implementing the event bus service, you must export it so that the Medusa
|
||||
|
||||
Create the file `index.ts` with the following content:
|
||||
|
||||
```ts title=services/event-bus-custom.ts
|
||||
```ts title="services/event-bus-custom.ts"
|
||||
import { ModuleExports } from "@medusajs/modules-sdk"
|
||||
|
||||
import { CustomEventBus } from "./services"
|
||||
@@ -226,7 +226,7 @@ You can test your module in the Medusa backend by referencing it in the configur
|
||||
|
||||
To do that, add the module to the exported configuration in `medusa-config.js` as follows:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
|
||||
@@ -23,7 +23,7 @@ The `eventBusService.subscribe` method receives the name of the event as a first
|
||||
|
||||
For example, here is the `OrderNotifierSubscriber` class created in `src/subscribers/order-notifier.ts`:
|
||||
|
||||
```ts title=src/subscribers/order-notifier.ts
|
||||
```ts title="src/subscribers/order-notifier.ts"
|
||||
class OrderNotifierSubscriber {
|
||||
constructor({ eventBusService }) {
|
||||
eventBusService.subscribe("order.placed", this.handleOrder)
|
||||
@@ -99,7 +99,7 @@ You can access any service through the dependencies injected to your subscriber
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/subscribers/order-notifier.ts
|
||||
```ts title="src/subscribers/order-notifier.ts"
|
||||
class OrderNotifierSubscriber {
|
||||
constructor({ productService, eventBusService }) {
|
||||
this.productService = productService
|
||||
@@ -115,7 +115,7 @@ class OrderNotifierSubscriber {
|
||||
|
||||
You can then use `this.productService` anywhere in your subscriber’s methods. For example:
|
||||
|
||||
```ts title=src/subscribers/order-notifier.ts
|
||||
```ts title="src/subscribers/order-notifier.ts"
|
||||
class OrderNotifierSubscriber {
|
||||
// ...
|
||||
handleOrder = async (data) => {
|
||||
|
||||
@@ -21,7 +21,7 @@ The subscriber file exports a default handler function, and the subscriber's con
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/subscribers/product-update-handler.ts
|
||||
```ts title="src/subscribers/product-update-handler.ts"
|
||||
import {
|
||||
ProductService,
|
||||
type SubscriberConfig,
|
||||
@@ -107,7 +107,7 @@ Within your subscriber, you may need to access the Medusa configuration exported
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/subscribers/product-update-handler.ts
|
||||
```ts title="src/subscribers/product-update-handler.ts"
|
||||
import {
|
||||
ProductService,
|
||||
type SubscriberConfig,
|
||||
|
||||
@@ -37,7 +37,7 @@ npm install @medusajs/event-bus-local
|
||||
|
||||
In `medusa-config.js`, add the following to the exported object:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
|
||||
@@ -55,7 +55,7 @@ Where `<YOUR_REDIS_URL>` is a connection URL to your Redis instance.
|
||||
|
||||
In `medusa-config.js`, add the following to the exported object:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
|
||||
@@ -39,7 +39,7 @@ You can enable a feature by using the backend configurations in `medusa-config.j
|
||||
|
||||
For example, to enable the Tax-Inclusive Pricing beta feature, add the following to the exported object in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
featureFlags: {
|
||||
tax_inclusive_pricing: true,
|
||||
|
||||
@@ -44,7 +44,7 @@ You can learn more about services and their naming convention in [this documenta
|
||||
|
||||
For example, create the file `src/services/local-file.ts` with the following content:
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
import { AbstractFileService } from "@medusajs/medusa"
|
||||
import {
|
||||
DeleteFileType,
|
||||
@@ -106,7 +106,7 @@ You can use a constructor to access services and resources registered in the dep
|
||||
|
||||
For example, the local service’s constructor could be useful to prepare the local upload directory:
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
// ...
|
||||
import * as fs from "fs"
|
||||
|
||||
@@ -139,7 +139,7 @@ Another example showcasing how to access resources using dependency injection:
|
||||
|
||||
<!-- eslint-disable prefer-rest-params -->
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
type InjectedDependencies = {
|
||||
logger: Logger
|
||||
}
|
||||
@@ -159,7 +159,7 @@ class LocalFileService extends AbstractFileService {
|
||||
|
||||
You can access the plugin options in the second parameter passed to the constructor:
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
class LocalFileService extends AbstractFileService {
|
||||
protected serverUrl = "http://localhost:9000"
|
||||
// ...
|
||||
@@ -206,7 +206,7 @@ The method is expected to return an object that has the following properties:
|
||||
|
||||
An example implementation of this method for the local file service:
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
class LocalFileService extends AbstractFileService {
|
||||
|
||||
async upload(
|
||||
@@ -254,7 +254,7 @@ The method is expected to return an object that has the following properties:
|
||||
|
||||
An example implementation of this method for the local file service:
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
class LocalFileService extends AbstractFileService {
|
||||
|
||||
async uploadProtected(
|
||||
@@ -286,7 +286,7 @@ This method is not expected to return anything.
|
||||
|
||||
An example implementation of this method for the local file service:
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
class LocalFileService extends AbstractFileService {
|
||||
|
||||
async delete(
|
||||
@@ -320,7 +320,7 @@ You can also return custom properties within the object.
|
||||
|
||||
An example implementation of this method for the local file service:
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
class LocalFileService extends AbstractFileService {
|
||||
|
||||
async getUploadStreamDescriptor({
|
||||
@@ -359,7 +359,7 @@ The method is expected to return a readable stream.
|
||||
|
||||
An example implementation of this method for the local file service:
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
class LocalFileService extends AbstractFileService {
|
||||
|
||||
async getDownloadStream({
|
||||
@@ -394,7 +394,7 @@ The method is expected to return a string, being the URL of the file.
|
||||
|
||||
An example implementation of this method for the local file service:
|
||||
|
||||
```ts title=src/services/local-file.ts
|
||||
```ts title="src/services/local-file.ts"
|
||||
class LocalFileService extends AbstractFileService {
|
||||
|
||||
async getPresignedDownloadUrl({
|
||||
@@ -452,7 +452,7 @@ Since the file is uploaded to a local directory `uploads`, you need to configure
|
||||
|
||||
To do that, create the file `src/api/index.ts` with the following content:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import type { MiddlewaresConfig } from "@medusajs/medusa"
|
||||
import express from "express"
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ The combination of these two commands running at the same time will compile the
|
||||
|
||||
For example, if you're making changes in the `medusa` package, run the following command inside the directory of the `medusa` package:
|
||||
|
||||
```bash title=packages/medusa
|
||||
```bash title="packages/medusa"
|
||||
yarn watch
|
||||
```
|
||||
|
||||
@@ -170,7 +170,7 @@ Make sure the `medusa-dev` command is also running to copy the changes automatic
|
||||
|
||||
Alternatively, you can manually run the `build` command every time you want to compile the changes:
|
||||
|
||||
```bash title=packages/medusa
|
||||
```bash title="packages/medusa"
|
||||
yarn build
|
||||
```
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ The `IdempotencyKeyService` includes methods that can be used to create and upda
|
||||
|
||||
You can create an idempotency key within an API Route using the `create` method of the `IdempotencyKeyService`:
|
||||
|
||||
```ts title=src/api/store/custom/route.ts
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -53,7 +53,7 @@ The method handles generating the idempotency key value and saving the idempoten
|
||||
|
||||
Alternatively, you can use the `initializeRequest` method that allows you to retrieve an idempotency key based on the value passed in the `Idempotency-Key` header of the request if it exists, or create a new key otherwise. For example:
|
||||
|
||||
```ts title=src/api/store/custom/route.ts
|
||||
```ts title="src/api/store/custom/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -38,7 +38,7 @@ When the loader is defined in a module, it receives the following parameters:
|
||||
|
||||
For example, this loader function resolves the `ProductService` and logs in the console the count of products in the Medusa backend:
|
||||
|
||||
```ts title=src/loaders/my-loader.ts
|
||||
```ts title="src/loaders/my-loader.ts"
|
||||
import {
|
||||
ProductService,
|
||||
ConfigModule,
|
||||
|
||||
@@ -16,7 +16,7 @@ To log a message, resolve the `logger` registration name using dependency inject
|
||||
|
||||
For example, to log a message in a [loader](../loaders/overview.mdx):
|
||||
|
||||
```ts title=src/loaders/my-loader.ts
|
||||
```ts title="src/loaders/my-loader.ts"
|
||||
import {
|
||||
ProductService,
|
||||
ConfigModule,
|
||||
@@ -85,7 +85,7 @@ If you configured the `LOG_LEVEL` environment variable to a level higher than th
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/loaders/my-loader.ts
|
||||
```ts title="src/loaders/my-loader.ts"
|
||||
import {
|
||||
ProductService,
|
||||
ConfigModule,
|
||||
|
||||
@@ -149,7 +149,7 @@ Where:
|
||||
|
||||
Here's an example implementation of `index.ts` from Medusa's Redis Cache module:
|
||||
|
||||
```ts title=index.ts
|
||||
```ts title="index.ts"
|
||||
import { ModuleExports } from "@medusajs/modules-sdk"
|
||||
|
||||
import Loader from "./loaders"
|
||||
@@ -172,7 +172,7 @@ export default moduleDefinition
|
||||
|
||||
To use your module in the Medusa backend, add your module to `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
@@ -200,7 +200,7 @@ The way you add your module depends on its type and what options it requires, if
|
||||
|
||||
When the module is installed as an NPM package, the value of the `resolve` property should be the name of that package. For example:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
@@ -238,7 +238,7 @@ You can reference your module in two ways:
|
||||
|
||||
1\. Referencing the directory: In this case, it's assumed that the `index.ts` file that contains the module definition is in the root of the directory you referenced. Using the above example, the file path would be in this case:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
@@ -253,7 +253,7 @@ module.exports = {
|
||||
|
||||
2\. Referencing `index` file: In this case, it's assumed that the `index.ts` or `index.js` file you're referencing includes the module definition. Using the above example, the file path would be in this case:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
@@ -272,7 +272,7 @@ By default, the module shares the same dependency container used across the Medu
|
||||
|
||||
The module's scope can be changed using the `resources` property available as part of the module's configurations:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
|
||||
@@ -35,7 +35,7 @@ Once you’re done, you should have a `package.json` created in the directory.
|
||||
|
||||
In your `package.json` file, add or update the following fields:
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
{
|
||||
// other fields
|
||||
"main": "dist/index.js",
|
||||
@@ -73,7 +73,7 @@ This adds the necessary dependencies for development and publishing, including t
|
||||
|
||||
If you don't already have a `tsconfig.json` file, create one in the root of your NPM project with the following content:
|
||||
|
||||
```json title=tsconfig.json
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
@@ -162,7 +162,7 @@ Where `module-name` is the name of your module.
|
||||
|
||||
In `medusa-config.js` on your Medusa backend, add your module to the exported configurations:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
|
||||
@@ -25,7 +25,7 @@ Creating a Notification Provider is as simple as creating a TypeScript or JavaS
|
||||
|
||||
For example, create the file `src/services/email-sender.ts` with the following content:
|
||||
|
||||
```ts title=src/services/email-sender.ts
|
||||
```ts title="src/services/email-sender.ts"
|
||||
import { AbstractNotificationService } from "@medusajs/medusa"
|
||||
import { EntityManager } from "typeorm"
|
||||
|
||||
@@ -263,7 +263,7 @@ After creating your Notification Provider Service, you must create a [Loader](..
|
||||
|
||||
Following the previous example, to make sure the `email-sender` Notification Provider handles the `order.placed` event, create the file `src/loaders/notification.ts` with the following content:
|
||||
|
||||
```ts title=src/loaders/notification.ts
|
||||
```ts title="src/loaders/notification.ts"
|
||||
import {
|
||||
MedusaContainer,
|
||||
NotificationService,
|
||||
|
||||
@@ -66,7 +66,7 @@ npm install
|
||||
|
||||
Then, make sure to remove the plugins and modules you removed from `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
// previously had plugins
|
||||
const plugins = []
|
||||
|
||||
@@ -86,7 +86,7 @@ These changes may already be available in your Medusa project. They're included
|
||||
|
||||
Start by updating your `tsconfig.json` with the following configurations:
|
||||
|
||||
```json title=tsconfig.json
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2019",
|
||||
@@ -127,7 +127,7 @@ The addition of `"jsx": "react-jsx"` specified how should TypeScript transform J
|
||||
|
||||
Next, create the file `tsconfig.server.json` with the following content:
|
||||
|
||||
```json title=tsconfig.server.json
|
||||
```json title="tsconfig.server.json"
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
@@ -142,7 +142,7 @@ This is the configuration that will be used to transpile your custom backend cod
|
||||
|
||||
Then, create the file `tsconfig.admin.json` with the following content:
|
||||
|
||||
```json title=tsconfig.admin.json
|
||||
```json title="tsconfig.admin.json"
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
@@ -157,7 +157,7 @@ This is the configuration that will be used when transpiling your admin code.
|
||||
|
||||
Finally, update the `build` scripts in your project and add a new `prepare` command:
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
"scripts": {
|
||||
// other scripts...
|
||||
"build": "cross-env npm run clean && npm run build:server && npm run build:admin",
|
||||
@@ -176,7 +176,7 @@ Each of these scripts do the following:
|
||||
|
||||
Furthermore, make sure to add `react` to `peerDependencies` along with `react-router-dom` if you're using it:
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
"peerDependencies": {
|
||||
// other dependencies...
|
||||
"react": "^18.2.0",
|
||||
@@ -330,7 +330,7 @@ Plugins often allow developers that will later use them to provide their own opt
|
||||
|
||||
Developers that use your plugin will pass options to your plugin in the `plugins` array in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -346,7 +346,7 @@ In your plugin's services, you can have access to the option in their constructo
|
||||
|
||||
For example:
|
||||
|
||||
```js title=src/service/my.ts
|
||||
```js title="src/service/my.ts"
|
||||
// In a service in your plugin
|
||||
class MyService extends TransactionBaseService {
|
||||
constructor(container, options) {
|
||||
@@ -370,7 +370,7 @@ All plugins accept an option named `enableUI`. This option is useful mainly if y
|
||||
|
||||
A developer using your plugin can pass the `enableUI` option as part of the plugin's options:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -387,7 +387,7 @@ If you're passing your plugin options to third-party services, make sure to omit
|
||||
|
||||
For example:
|
||||
|
||||
```js title=src/service/test.ts
|
||||
```js title="src/service/test.ts"
|
||||
// In a service in your plugin
|
||||
class MyService extends TransactionBaseService {
|
||||
constructor(container, options) {
|
||||
|
||||
@@ -76,7 +76,7 @@ All plugins accept an option named `enableUI`. This option allows you to disable
|
||||
|
||||
You can set the `enableUI` value by passing it as part of the plugin's configurations:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ Before publishing your plugin, make sure you've set the following fields in your
|
||||
<TabItem value="without-admin" label="Without Admin Customizations" default>
|
||||
Make sure you add the `publish` script to your `scripts` field:
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
"scripts": {
|
||||
// other scripts...
|
||||
"build": "cross-env npm run clean && tsc -p tsconfig.json",
|
||||
@@ -64,7 +64,7 @@ Before publishing your plugin, make sure you've set the following fields in your
|
||||
|
||||
Then, add the following `prepare` and `build` scripts to your `scripts`
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
"scripts": {
|
||||
// other scripts...
|
||||
"build:server": "cross-env npm run clean && tsc -p tsconfig.json",
|
||||
@@ -92,7 +92,7 @@ So, you can ignore files and directories like `src` from the final published NPM
|
||||
|
||||
To do that, create the file `.npmignore` with the following content:
|
||||
|
||||
```bash title=.npmignore
|
||||
```bash title=".npmignore"
|
||||
/lib
|
||||
node_modules
|
||||
.DS_store
|
||||
|
||||
@@ -43,7 +43,7 @@ For the example in this tutorial, you can create the file `src/loaders/publish.t
|
||||
|
||||
To create a scheduled job, add the following code in the file you created, which is `src/loaders/publish.ts` in this example:
|
||||
|
||||
```ts title=src/loaders/publish.ts
|
||||
```ts title="src/loaders/publish.ts"
|
||||
import { MedusaContainer } from "@medusajs/medusa"
|
||||
|
||||
const publishJob = async (
|
||||
|
||||
@@ -35,7 +35,7 @@ The scheduled job file exports a default handler function, and the scheduled job
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/loaders/publish.ts
|
||||
```ts title="src/loaders/publish.ts"
|
||||
import {
|
||||
type ProductService,
|
||||
type ScheduledJobConfig,
|
||||
|
||||
@@ -35,7 +35,7 @@ You can learn more about services and their naming convention in [this documenta
|
||||
|
||||
For example, create the file `src/services/my-search.ts` with the following content:
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
import { AbstractSearchService } from "@medusajs/utils"
|
||||
|
||||
class MySearchService extends AbstractSearchService {
|
||||
@@ -101,7 +101,7 @@ For example:
|
||||
|
||||
<!-- eslint-disable prefer-rest-params -->
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
// ...
|
||||
import { ProductService } from "@medusajs/medusa"
|
||||
|
||||
@@ -127,7 +127,7 @@ You can access the plugin options in the second parameter passed to the construc
|
||||
|
||||
<!-- eslint-disable prefer-rest-params -->
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
// ...
|
||||
|
||||
class MySearchService extends AbstractSearchService {
|
||||
@@ -177,7 +177,7 @@ The method does not require any specific data type to be returned.
|
||||
|
||||
An example implementation, assuming `client_` would interact with a third-party service:
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
class MySearchService extends AbstractSearchService {
|
||||
// ...
|
||||
|
||||
@@ -195,7 +195,7 @@ The method accepts one parameter, which is a string indicating the name of the i
|
||||
|
||||
An example implementation, assuming `client_` would interact with a third-party service:
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
class MySearchService extends AbstractSearchService {
|
||||
// ...
|
||||
|
||||
@@ -221,7 +221,7 @@ The method should return the response of saving the documents in the search engi
|
||||
|
||||
An example implementation, assuming `client_` would interact with a third-party service:
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
class MySearchService extends AbstractSearchService {
|
||||
// ...
|
||||
|
||||
@@ -250,7 +250,7 @@ The method should return the response of saving the documents in the search engi
|
||||
|
||||
An example implementation, assuming `client_` would interact with a third-party service:
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
class MySearchService extends AbstractSearchService {
|
||||
// ...
|
||||
|
||||
@@ -282,7 +282,7 @@ The method should return the response of deleting the document in the search eng
|
||||
|
||||
An example implementation, assuming `client_` would interact with a third-party service:
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
class MySearchService extends AbstractSearchService {
|
||||
// ...
|
||||
|
||||
@@ -306,7 +306,7 @@ The method should return the response of deleting the documents of that index in
|
||||
|
||||
An example implementation, assuming `client_` would interact with a third-party service:
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
class MySearchService extends AbstractSearchService {
|
||||
// ...
|
||||
|
||||
@@ -333,7 +333,7 @@ Although there’s no required data format or type to be returned to the method,
|
||||
|
||||
An example implementation, assuming `client_` would interact with a third-party service:
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
class MySearchService extends AbstractSearchService {
|
||||
// ...
|
||||
|
||||
@@ -366,7 +366,7 @@ The method should return the response of updating the index in the search engine
|
||||
|
||||
An example implementation, assuming `client_` would interact with a third-party service:
|
||||
|
||||
```ts title=src/services/my-search.ts
|
||||
```ts title="src/services/my-search.ts"
|
||||
class MySearchService extends AbstractSearchService {
|
||||
// ...
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ To create a service, create a TypeScript or JavaScript file in `src/services` to
|
||||
|
||||
For example, if you want to create a service `PostService`, eventually registered as `postService`, create the file `post.ts` in `src/services` with the following content:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
|
||||
class PostService extends TransactionBaseService {
|
||||
@@ -53,7 +53,7 @@ As the service extends the `TransactionBaseService` class, all resources registe
|
||||
|
||||
So, if you want your service to use another service, add it as part of your constructor’s dependencies and set it to a field inside your service’s class:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import { ProductService } from "@medusajs/medusa"
|
||||
import { PostRepository } from "../repositories/post"
|
||||
|
||||
@@ -70,7 +70,7 @@ class PostService extends TransactionBaseService {
|
||||
|
||||
Then, you can use that service anywhere in your custom service. For example:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
class PostService extends TransactionBaseService {
|
||||
// ...
|
||||
async getProductCount() {
|
||||
@@ -91,7 +91,7 @@ However, to actually get an instance of the repository within the service's meth
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import { PostRepository } from "../repositories/post"
|
||||
|
||||
class PostService extends TransactionBaseService {
|
||||
@@ -131,7 +131,7 @@ The data returned by the function passed as a parameter to the `atomicPhase_` me
|
||||
|
||||
For example, the `PostService`'s `create` method with the `atomicPhase_` method:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
class PostService extends TransactionBaseService {
|
||||
protected postRepository_: typeof PostRepository
|
||||
// ...
|
||||
@@ -169,7 +169,7 @@ There are three lifetime types:
|
||||
|
||||
You can set the lifetime of your service by setting the `LIFE_TIME` static property:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
import { Lifetime } from "awilix"
|
||||
|
||||
@@ -188,7 +188,7 @@ Within your service, you may need to access the Medusa configuration exported fr
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import {
|
||||
ConfigModule,
|
||||
TransactionBaseService,
|
||||
@@ -228,7 +228,7 @@ The `@medusajs/medusa` package also provides a `buildQuery` method that allows y
|
||||
|
||||
So, for example, to create a method that retrieves a list of posts and the total number of posts available:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import {
|
||||
FindConfig,
|
||||
Selector,
|
||||
@@ -260,7 +260,7 @@ In addition, you can expand relations when retrieving a single item with the hel
|
||||
|
||||
For example, to create a method that retrieves a single post:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import {
|
||||
FindConfig,
|
||||
TransactionBaseService,
|
||||
@@ -319,7 +319,7 @@ This assumes you're handling errors in your custom API Route as explained [here]
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/post.ts
|
||||
```ts title="src/services/post.ts"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
|
||||
class PostService extends TransactionBaseService {
|
||||
|
||||
@@ -33,7 +33,7 @@ In the file, you can import the original service from the Medusa core, then crea
|
||||
|
||||
For example, to extend the Product service:
|
||||
|
||||
```ts title=src/services/product.ts
|
||||
```ts title="src/services/product.ts"
|
||||
import {
|
||||
ProductService as MedusaProductService,
|
||||
} from "@medusajs/medusa"
|
||||
@@ -51,7 +51,7 @@ Within the service, you can add new methods or extend existing ones.
|
||||
|
||||
You can also change the lifetime of the service:
|
||||
|
||||
```ts title=src/services/product.ts
|
||||
```ts title="src/services/product.ts"
|
||||
import { Lifetime } from "awilix"
|
||||
import {
|
||||
ProductService as MedusaProductService,
|
||||
|
||||
@@ -50,7 +50,7 @@ After initialization, you can use the client's properties and methods to send re
|
||||
|
||||
Make sure to set `moduleResolution` in your `tsconfig.json` to `nodenext` or `node`:
|
||||
|
||||
```json title=tsconfig.json
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "nodenext",
|
||||
|
||||
@@ -54,7 +54,7 @@ The `MedusaProvider` requires two props:
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/App.ts
|
||||
```tsx title="src/App.ts"
|
||||
import { MedusaProvider } from "medusa-react"
|
||||
import Storefront from "./Storefront"
|
||||
import { QueryClient } from "@tanstack/react-query"
|
||||
@@ -90,7 +90,7 @@ Could not find a declaration file for module 'medusa-react'
|
||||
|
||||
Make sure to set `moduleResolution` in your `tsconfig.json` to `nodenext` or `node`:
|
||||
|
||||
```json title=tsconfig.json
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "nodenext",
|
||||
@@ -115,7 +115,7 @@ To fetch data from the Medusa backend (in other words, perform `GET` requests),
|
||||
|
||||
For example, to fetch products from your Medusa backend:
|
||||
|
||||
```tsx title=src/Products.ts
|
||||
```tsx title="src/Products.ts"
|
||||
import { Product } from "@medusajs/medusa"
|
||||
import { useProducts } from "medusa-react"
|
||||
|
||||
@@ -146,7 +146,7 @@ Instead of the `data` field, the response data is flattened and is part of the h
|
||||
|
||||
If the request accepts any parameters, they can be passed as parameters to the `mutate` request. For example:
|
||||
|
||||
```tsx title=src/Products.ts
|
||||
```tsx title="src/Products.ts"
|
||||
const { products } = useProducts({
|
||||
expand: "variants",
|
||||
})
|
||||
@@ -160,7 +160,7 @@ To create, update, or delete data on the Medusa backend (in other words, perform
|
||||
|
||||
For example, to create a cart:
|
||||
|
||||
```tsx title=src/Cart.ts
|
||||
```tsx title="src/Cart.ts"
|
||||
import { useCreateCart } from "medusa-react"
|
||||
|
||||
const Cart = () => {
|
||||
@@ -360,7 +360,7 @@ The request returns an object containing keys like `mutation` which is a functio
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/admin/routes/blog/posts/page.tsx
|
||||
```tsx title="src/admin/routes/blog/posts/page.tsx"
|
||||
import { useAdminCustomPost } from "medusa-react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
|
||||
@@ -438,7 +438,7 @@ The request returns an object containing keys like `mutation` which is a functio
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/admin/routes/blog/posts/[id]/page.tsx
|
||||
```tsx title="src/admin/routes/blog/posts/[id]/page.tsx"
|
||||
import { useAdminCustomDelete } from "medusa-react"
|
||||
import { useNavigate, useParams } from "react-router-dom"
|
||||
|
||||
@@ -502,7 +502,7 @@ It accepts an object with the following properties:
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/Products.ts
|
||||
```tsx title="src/Products.ts"
|
||||
import { formatVariantPrice } from "medusa-react"
|
||||
import { Product, ProductVariant } from "@medusajs/medusa"
|
||||
|
||||
@@ -542,7 +542,7 @@ It accepts an object with the following properties:
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/Products.ts
|
||||
```tsx title="src/Products.ts"
|
||||
import { computeVariantPrice } from "medusa-react"
|
||||
import { Product, ProductVariant } from "@medusajs/medusa"
|
||||
|
||||
@@ -587,7 +587,7 @@ It accepts an object with the following properties:
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/MyComponent.ts
|
||||
```tsx title="src/MyComponent.ts"
|
||||
import { formatAmount } from "medusa-react"
|
||||
|
||||
const MyComponent = () => {
|
||||
@@ -617,7 +617,7 @@ It accepts an object with the following properties:
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/MyComponent.ts
|
||||
```tsx title="src/MyComponent.ts"
|
||||
import { computeAmount } from "medusa-react"
|
||||
|
||||
const MyComponent = () => {
|
||||
@@ -655,7 +655,7 @@ To use `CartProvider`, you first have to insert it somewhere in your component t
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/App.ts
|
||||
```tsx title="src/App.ts"
|
||||
import { CartProvider, MedusaProvider } from "medusa-react"
|
||||
import Storefront from "./Storefront"
|
||||
import { QueryClient } from "@tanstack/react-query"
|
||||
@@ -695,7 +695,7 @@ The `useCart` hook returns an object with the following properties:
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/Cart.ts
|
||||
```tsx title="src/Cart.ts"
|
||||
import * as React from "react"
|
||||
|
||||
import { useCart } from "medusa-react"
|
||||
@@ -745,7 +745,7 @@ To use `SessionProvider`, you first have to insert it somewhere in your componen
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/App.ts
|
||||
```tsx title="src/App.ts"
|
||||
import { SessionProvider, MedusaProvider } from "medusa-react"
|
||||
import Storefront from "./Storefront"
|
||||
import { QueryClient } from "@tanstack/react-query"
|
||||
@@ -773,7 +773,7 @@ Then, in any of the child components, you can use the `useSessionHook` hook expo
|
||||
|
||||
For example:
|
||||
|
||||
```tsx title=src/Products.ts
|
||||
```tsx title="src/Products.ts"
|
||||
const Products = () => {
|
||||
const { addItem } = useSessionCart()
|
||||
// ...
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ Fulfillment providers are loaded and installed on the backend startup.
|
||||
|
||||
The first step is to create a JavaScript or TypeScript file under `src/services`. For example, create the file `src/services/my-fulfillment.ts` with the following content:
|
||||
|
||||
```ts title=src/services/my-fulfillment.ts
|
||||
```ts title="src/services/my-fulfillment.ts"
|
||||
import {
|
||||
AbstractFulfillmentService,
|
||||
Cart,
|
||||
|
||||
@@ -60,7 +60,7 @@ The first step to create a payment processor is to create a JavaScript or TypeSc
|
||||
|
||||
For example, create the file `src/services/my-payment-processor.ts` with the following content:
|
||||
|
||||
```ts title=src/services/my-payment-processor.ts
|
||||
```ts title="src/services/my-payment-processor.ts"
|
||||
import {
|
||||
AbstractPaymentProcessor,
|
||||
PaymentProcessorContext,
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ This guide only explains how to override the cart completion strategy. It’s hi
|
||||
|
||||
Create a TypeScript or JavaScript file in `src/strategies` of your Medusa backend project with a class that extends the `AbstractCartCompletionStrategy` class:
|
||||
|
||||
```ts title=src/strategies/cart-completion.ts
|
||||
```ts title="src/strategies/cart-completion.ts"
|
||||
import {
|
||||
AbstractCartCompletionStrategy,
|
||||
CartCompletionResponse,
|
||||
@@ -52,7 +52,7 @@ You can use a constructor to access services and resources registered in the dep
|
||||
|
||||
<!-- eslint-disable prefer-rest-params -->
|
||||
|
||||
```ts title=src/strategies/cart-completion.ts
|
||||
```ts title="src/strategies/cart-completion.ts"
|
||||
// ...
|
||||
import { IdempotencyKeyService } from "@medusajs/medusa"
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ To subscribe to an event, you must create a [subscriber](../../../development/ev
|
||||
|
||||
Create the file `src/subscribers/customer-confirmation.ts` with the following content:
|
||||
|
||||
```ts title=src/subscribers/customer-confirmation.ts
|
||||
```ts title="src/subscribers/customer-confirmation.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -70,7 +70,7 @@ In this method, you should typically send an email to the customer. You can plac
|
||||
|
||||
For example, you can implement this subscriber to send emails using [SendGrid](../../../plugins/notifications/sendgrid.mdx):
|
||||
|
||||
```ts title=src/subscribers/customer-confirmation.ts
|
||||
```ts title="src/subscribers/customer-confirmation.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -117,7 +117,7 @@ If the notification provider you’re using already implements the logic to hand
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/loaders/customer-confirmation.ts
|
||||
```ts title="src/loaders/customer-confirmation.ts"
|
||||
import {
|
||||
MedusaContainer,
|
||||
NotificationService,
|
||||
|
||||
@@ -41,7 +41,7 @@ To subscribe to and handle an event, you must create a [subscriber](../../../dev
|
||||
|
||||
Create the file `src/subscribers/gift-card.ts` with the following content:
|
||||
|
||||
```ts title=src/subscribers/gift-card.ts
|
||||
```ts title="src/subscribers/gift-card.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -72,7 +72,7 @@ In this method, you should typically send an email to the customer. You can plac
|
||||
|
||||
For example, you can implement this subscriber to send emails using [SendGrid](../../../plugins/notifications/sendgrid.mdx):
|
||||
|
||||
```ts title=src/subscribers/gift-card.ts
|
||||
```ts title="src/subscribers/gift-card.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -125,7 +125,7 @@ If the notification provider you’re using already implements the logic to hand
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/loaders/gift-card-event.ts
|
||||
```ts title="src/loaders/gift-card-event.ts"
|
||||
import {
|
||||
MedusaContainer,
|
||||
NotificationService,
|
||||
|
||||
@@ -47,7 +47,7 @@ Create a file in the `src/services` directory that will hold your custom invento
|
||||
|
||||
In that file, add the following content:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
import {
|
||||
CreateInventoryItemInput,
|
||||
CreateInventoryLevelInput,
|
||||
@@ -302,7 +302,7 @@ type InventoryItemDTO = {
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -360,7 +360,7 @@ type ReservationItemDTO = {
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -417,7 +417,7 @@ type InventoryLevelDTO = {
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -452,7 +452,7 @@ This method is expected to return the inventory item as an object.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -491,7 +491,7 @@ This method is expected to return the inventory level as an object.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -530,7 +530,7 @@ This method is expected to return the inventory level as an object.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -572,7 +572,7 @@ This method is expected to return the newly created reservation item.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -605,7 +605,7 @@ This method is expected to return the newly created inventory item.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -643,7 +643,7 @@ This method is expected to return the newly created inventory level.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -677,7 +677,7 @@ This method is expected to return the updated reservation item.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -719,7 +719,7 @@ This method is expected to return the updated inventory item.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -766,7 +766,7 @@ This method is expected to return the updated inventory level.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -810,7 +810,7 @@ This method is not expected to return anything.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -843,7 +843,7 @@ This method is not expected to return anything.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -878,7 +878,7 @@ This method is not expected to return anything.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -913,7 +913,7 @@ This method is not expected to return anything.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -947,7 +947,7 @@ This method is not expected to return anything.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -984,7 +984,7 @@ This method is not expected to return anything.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -1021,7 +1021,7 @@ This method is expected to return the updated location level.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -1074,7 +1074,7 @@ This method is expected to return a boolean value indicating whether the invento
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -1110,7 +1110,7 @@ This method is expected to return a number being the available quantity of the i
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -1143,7 +1143,7 @@ This method is expected to return a number being the stocked quantity of the ite
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -1176,7 +1176,7 @@ This method is expected to return a number being the reserved quantity of the it
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/inventory.ts
|
||||
```ts title="src/services/inventory.ts"
|
||||
class InventoryService implements IInventoryService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
|
||||
+7
-7
@@ -47,7 +47,7 @@ Create a file in the `src/services` directory that will hold your custom stock l
|
||||
|
||||
In that file, add the following content:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
```ts title="src/services/stock-location.ts"
|
||||
import {
|
||||
CreateStockLocationInput,
|
||||
FilterableStockLocationProps,
|
||||
@@ -168,7 +168,7 @@ type StockLocationDTO = {
|
||||
|
||||
Here’s an example implementation of the method:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
```ts title="src/services/stock-location.ts"
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -199,7 +199,7 @@ It accepts the exact same parameters as the [list method](#implementing-list-met
|
||||
|
||||
Here’s an example implementation of the method:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
```ts title="src/services/stock-location.ts"
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -234,7 +234,7 @@ This method returns the location as an object.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
```ts title="src/services/stock-location.ts"
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -275,7 +275,7 @@ The method is expected to return the created location as an object.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
```ts title="src/services/stock-location.ts"
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -313,7 +313,7 @@ This method is expected to return the updated location object.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
```ts title="src/services/stock-location.ts"
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
@@ -348,7 +348,7 @@ This method is not expected to return anything.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/services/stock-location.ts
|
||||
```ts title="src/services/stock-location.ts"
|
||||
class StockLocationService implements IStockLocationService {
|
||||
// ...
|
||||
@InjectEntityManager()
|
||||
|
||||
@@ -45,7 +45,7 @@ You can learn more about subscribers in the [Subscribers documentation](../../
|
||||
|
||||
Create the file `src/subscribers/order-claim.ts` with the following content:
|
||||
|
||||
```ts title=src/subscribers/order-claim.ts
|
||||
```ts title="src/subscribers/order-claim.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -88,7 +88,7 @@ In this method, you should typically send an email to the customer. You can plac
|
||||
|
||||
For example, you can implement this subscriber to send emails using SendGrid:
|
||||
|
||||
```ts title=src/subscribers/order-claim.ts
|
||||
```ts title="src/subscribers/order-claim.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -129,7 +129,7 @@ If the notification provider you’re using already implements the logic to hand
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/loaders/order-claim.ts
|
||||
```ts title="src/loaders/order-claim.ts"
|
||||
import {
|
||||
MedusaContainer,
|
||||
NotificationService,
|
||||
|
||||
@@ -37,7 +37,7 @@ To subscribe to an event, you must create a [subscriber](../../../development/ev
|
||||
|
||||
Create the file `src/subscribers/order-placed.ts` with the following content:
|
||||
|
||||
```ts title=src/subscribers/order-placed.ts
|
||||
```ts title="src/subscribers/order-placed.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -74,7 +74,7 @@ This example is only used to illustrate how the functionality can be implemented
|
||||
|
||||
For example, you can implement this subscriber to send emails using [SendGrid](../../../plugins/notifications/sendgrid.mdx):
|
||||
|
||||
```ts title=src/subscribers/order-placed.ts
|
||||
```ts title="src/subscribers/order-placed.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -129,7 +129,7 @@ If the notification provider you’re using already implements the logic to hand
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/loaders/customer-confirmation.ts
|
||||
```ts title="src/loaders/customer-confirmation.ts"
|
||||
import {
|
||||
MedusaContainer,
|
||||
NotificationService,
|
||||
|
||||
@@ -25,7 +25,7 @@ Medusa provides the necessary features to build a customizable shopping experien
|
||||
<LargeCardList colSize={6}>
|
||||
<LargeCard
|
||||
Icon={Icons['check-circle-solid']}
|
||||
title='Orders'
|
||||
title="'Orders'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/orders/overview'
|
||||
@@ -42,7 +42,7 @@ Medusa provides the necessary features to build a customizable shopping experien
|
||||
</LargeCard>
|
||||
<LargeCard
|
||||
Icon={Icons['building-solid']}
|
||||
title='Inventory (Multi-Warehouse)'
|
||||
title="'Inventory (Multi-Warehouse)'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/multiwarehouse/overview'
|
||||
@@ -57,7 +57,7 @@ Medusa provides the necessary features to build a customizable shopping experien
|
||||
</LargeCard>
|
||||
<LargeCard
|
||||
Icon={Icons['shopping-cart-solid']}
|
||||
title='Cart and Checkout'
|
||||
title="'Cart and Checkout'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/carts-and-checkout/overview'
|
||||
@@ -73,7 +73,7 @@ Medusa provides the necessary features to build a customizable shopping experien
|
||||
</LargeCard>
|
||||
<LargeCard
|
||||
Icon={Icons['users-solid']}
|
||||
title='Customers'
|
||||
title="'Customers'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/customers/overview'
|
||||
@@ -95,7 +95,7 @@ Medusa's products configuration allows managing products of different types incl
|
||||
<LargeCardList colSize={6}>
|
||||
<LargeCard
|
||||
Icon={Icons['tag-solid']}
|
||||
title='Products'
|
||||
title="'Products'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/products/overview'
|
||||
@@ -112,7 +112,7 @@ Medusa's products configuration allows managing products of different types incl
|
||||
</LargeCard>
|
||||
<LargeCard
|
||||
Icon={Icons['gift-solid']}
|
||||
title='Gift Cards'
|
||||
title="'Gift Cards'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/gift-cards/overview'
|
||||
@@ -129,7 +129,7 @@ Medusa's products configuration allows managing products of different types incl
|
||||
|
||||
<LargeCard
|
||||
Icon={Icons['currency-dollar-solid']}
|
||||
title='Price Lists'
|
||||
title="'Price Lists'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/price-lists/overview'
|
||||
@@ -146,7 +146,7 @@ Medusa's products configuration allows managing products of different types incl
|
||||
|
||||
<LargeCard
|
||||
Icon={Icons['receipt-percent']}
|
||||
title='Discounts'
|
||||
title="'Discounts'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/discounts/overview'
|
||||
@@ -169,7 +169,7 @@ Medusa's multi-region setup and sales channels allow businesses to sell internat
|
||||
<LargeCardList colSize={6}>
|
||||
<LargeCard
|
||||
Icon={Icons['globe-europe-solid']}
|
||||
title='Region and Currencies'
|
||||
title="'Region and Currencies'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/regions-and-currencies/overview'
|
||||
@@ -185,7 +185,7 @@ Medusa's multi-region setup and sales channels allow businesses to sell internat
|
||||
</LargeCard>
|
||||
<LargeCard
|
||||
Icon={Icons['cash-solid']}
|
||||
title='Taxes'
|
||||
title="'Taxes'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/taxes/overview'
|
||||
@@ -203,7 +203,7 @@ Medusa's multi-region setup and sales channels allow businesses to sell internat
|
||||
|
||||
<LargeCard
|
||||
Icon={Icons['channels-solid']}
|
||||
title='Sales Channels'
|
||||
title="'Sales Channels'"
|
||||
action={{
|
||||
label: 'Learn more',
|
||||
href: '/modules/sales-channels/overview'
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ If you’re interested in learning what a price selection strategy is and how it
|
||||
|
||||
Create a TypeScript or JavaScript file in `src/strategies` of your Medusa backend project with a class that extends the `AbstractPriceSelectionStrategy` class:
|
||||
|
||||
```ts title=src/strategies/price.ts
|
||||
```ts title="src/strategies/price.ts"
|
||||
import {
|
||||
AbstractPriceSelectionStrategy,
|
||||
PriceSelectionContext,
|
||||
@@ -51,7 +51,7 @@ You can resolve resources like services or repositories using [dependency inject
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/strategies/price.ts
|
||||
```ts title="src/strategies/price.ts"
|
||||
import {
|
||||
AbstractPriceSelectionStrategy,
|
||||
CustomerService,
|
||||
|
||||
@@ -90,7 +90,7 @@ If you are using an existing Medusa database, you can skip this step.
|
||||
|
||||
Migrations are used to create your database schema. Before you can run migrations, add in your `package.json` the following scripts:
|
||||
|
||||
```json title=package.json
|
||||
```json title="package.json"
|
||||
"scripts": {
|
||||
//...other scripts
|
||||
"product:migrations:run": "medusa-product-migrations-up",
|
||||
@@ -103,7 +103,7 @@ The first command runs the migrations, and the second command allows you to opti
|
||||
<Details>
|
||||
<Summary>Seed file</Summary>
|
||||
|
||||
```js title=seed-data.js
|
||||
```js title="seed-data.js"
|
||||
const productCategoriesData = [
|
||||
{
|
||||
id: "category-0",
|
||||
@@ -210,7 +210,7 @@ Next.js uses Webpack for compilation. Since quite a few of the dependencies used
|
||||
|
||||
To do that, add the `serverComponentsExternalPackages` option in `next.config.js`:
|
||||
|
||||
```js title=next.config.js
|
||||
```js title="next.config.js"
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
experimental: {
|
||||
@@ -235,7 +235,7 @@ This guide uses Next.js's App Router.
|
||||
|
||||
For example, create the file `app/api/products/route.ts` with the following content:
|
||||
|
||||
```ts title=app/api/products/route.ts
|
||||
```ts title="app/api/products/route.ts"
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
@@ -271,7 +271,7 @@ This section includes some examples of the different functionalities or ways you
|
||||
|
||||
### List Products
|
||||
|
||||
```ts title=app/api/products/route.ts
|
||||
```ts title="app/api/products/route.ts"
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
@@ -289,7 +289,7 @@ export async function GET(request: Request) {
|
||||
|
||||
### Retrieve Product by Id
|
||||
|
||||
```ts title=app/api/product/[id]/route.ts
|
||||
```ts title="app/api/product/[id]/route.ts"
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
@@ -313,7 +313,7 @@ export async function GET(
|
||||
|
||||
### Retrieve Product by Handle
|
||||
|
||||
```ts title=app/api/product/[handle]/route.ts
|
||||
```ts title="app/api/product/[handle]/route.ts"
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
@@ -337,7 +337,7 @@ export async function GET(
|
||||
|
||||
### Retrieve Categories
|
||||
|
||||
```ts title=app/api/categories/route.ts
|
||||
```ts title="app/api/categories/route.ts"
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
@@ -355,7 +355,7 @@ export async function GET(request: Request) {
|
||||
|
||||
### Retrieve Category by Handle
|
||||
|
||||
```ts title=app/api/category/[handle]/route.ts
|
||||
```ts title="app/api/category/[handle]/route.ts"
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
|
||||
@@ -19,7 +19,7 @@ A tax provider class should be defined in a TypeScript or JavaScript file under
|
||||
|
||||
For example, you can create the file `src/services/my-tax.ts` with the following content:
|
||||
|
||||
```ts title=src/services/my-tax.ts
|
||||
```ts title="src/services/my-tax.ts"
|
||||
import {
|
||||
AbstractTaxService,
|
||||
ItemTaxCalculationLine,
|
||||
@@ -49,7 +49,7 @@ Since the class extends `AbstractTaxService`, it must implement its abstract met
|
||||
|
||||
You can use a constructor to access services and resources registered in the dependency container using dependency injection. For example:
|
||||
|
||||
```ts title=src/services/my-tax.ts
|
||||
```ts title="src/services/my-tax.ts"
|
||||
// ...
|
||||
import { LineItemService } from "@medusajs/medusa"
|
||||
|
||||
@@ -79,7 +79,7 @@ Every tax provider must have a unique identifier. The identifier is defined as a
|
||||
|
||||
Add the static property `identifier` in your tax provider class:
|
||||
|
||||
```ts title=src/services/my-tax.ts
|
||||
```ts title="src/services/my-tax.ts"
|
||||
class MyTaxService extends AbstractTaxService {
|
||||
static identifier = "my-tax"
|
||||
// ...
|
||||
@@ -161,7 +161,7 @@ The Medusa backend determines whether an object in the returned array is a shipp
|
||||
|
||||
For example, the `system` tax provider returns the tax calculation line items in the first parameter and the tax calculation shipping methods in the second parameter as is:
|
||||
|
||||
```ts title=src/services/my-tax.ts
|
||||
```ts title="src/services/my-tax.ts"
|
||||
// ...
|
||||
|
||||
class SystemTaxService extends AbstractTaxService {
|
||||
|
||||
@@ -21,7 +21,7 @@ A tax calculation strategy should be defined in a TypeScript or JavaScript file
|
||||
|
||||
For example, you can create the file `src/strategies/tax-calculation.ts` with the following content:
|
||||
|
||||
```ts title=src/strategies/tax-calculation.ts
|
||||
```ts title="src/strategies/tax-calculation.ts"
|
||||
import {
|
||||
ITaxCalculationStrategy,
|
||||
LineItem,
|
||||
@@ -52,7 +52,7 @@ Note that you add a basic implementation of the `calculate` method because it’
|
||||
|
||||
You can use a constructor to access services and resources registered in the dependency container using dependency injection. For example:
|
||||
|
||||
```ts title=src/strategies/tax-calculation.ts
|
||||
```ts title="src/strategies/tax-calculation.ts"
|
||||
// ...
|
||||
import {
|
||||
LineItemService,
|
||||
|
||||
@@ -52,7 +52,7 @@ You can learn how to [retrieve and use services](../../../development/services/c
|
||||
|
||||
Another way you can use the `CartService` to calculate taxes is using the method `decorateTotals`:
|
||||
|
||||
```ts title=src/api/store/line-taxes/[cart_id]/route.ts
|
||||
```ts title="src/api/store/line-taxes/[cart_id]/route.ts"
|
||||
import { CartService } from "@medusajs/medusa"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
|
||||
@@ -56,7 +56,7 @@ So, the first step would be to create the `Role` and `Permission` entities to re
|
||||
|
||||
Create the file `src/models/role.ts` with the following content:
|
||||
|
||||
```ts title=src/models/role.ts
|
||||
```ts title="src/models/role.ts"
|
||||
import {
|
||||
BeforeInsert,
|
||||
Column,
|
||||
@@ -129,7 +129,7 @@ So, the first step would be to create the `Role` and `Permission` entities to re
|
||||
|
||||
Then, create the file `src/repositories/role.ts` with the following content:
|
||||
|
||||
```ts title=src/repositories/role.ts
|
||||
```ts title="src/repositories/role.ts"
|
||||
import { Role } from "../models/role"
|
||||
import {
|
||||
dataSource,
|
||||
@@ -143,7 +143,7 @@ So, the first step would be to create the `Role` and `Permission` entities to re
|
||||
|
||||
Next, create the file `src/models/permission.ts` with the following content:
|
||||
|
||||
```ts title=src/models/permission.ts
|
||||
```ts title="src/models/permission.ts"
|
||||
import {
|
||||
BeforeInsert,
|
||||
Column,
|
||||
@@ -182,7 +182,7 @@ So, the first step would be to create the `Role` and `Permission` entities to re
|
||||
|
||||
Then, create the file `src/repositories/permission.ts` with the following content:
|
||||
|
||||
```ts title=src/repositories/permission.ts
|
||||
```ts title="src/repositories/permission.ts"
|
||||
import { Permission } from "../models/permission"
|
||||
import {
|
||||
dataSource,
|
||||
@@ -198,7 +198,7 @@ So, the first step would be to create the `Role` and `Permission` entities to re
|
||||
|
||||
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,
|
||||
@@ -228,7 +228,7 @@ So, the first step would be to create the `Role` and `Permission` entities to re
|
||||
|
||||
Next, create the file `src/models/store.ts` with the following content:
|
||||
|
||||
```ts title=src/models/store.ts
|
||||
```ts title="src/models/store.ts"
|
||||
import { Entity, JoinColumn, OneToMany } from "typeorm"
|
||||
import {
|
||||
// alias the core entity to not cause a naming conflict
|
||||
@@ -248,7 +248,7 @@ So, the first step would be to create the `Role` and `Permission` entities to re
|
||||
|
||||
Optionally, if you’re using TypeScript, create the file `src/index.d.ts` with the following content:
|
||||
|
||||
```ts title=src/index.d.ts
|
||||
```ts title="src/index.d.ts"
|
||||
import { Role } from "./models/role"
|
||||
|
||||
export declare module "@medusajs/medusa/dist/models/user" {
|
||||
@@ -272,7 +272,7 @@ So, the first step would be to create the `Role` and `Permission` entities to re
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```ts title=src/migrations/1693225851284-AddRolesAndPermissions.ts
|
||||
```ts title="src/migrations/1693225851284-AddRolesAndPermissions.ts"
|
||||
import { MigrationInterface, QueryRunner, Table, TableIndex } from "typeorm"
|
||||
|
||||
export class AddRolesAndPermissions1693225851284 implements MigrationInterface {
|
||||
@@ -352,7 +352,7 @@ Since the Medusa backend uses Express, you can create a middleware and attach it
|
||||
|
||||
Create the file `src/api/middlewares.ts` with the following content:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import type {
|
||||
MiddlewaresConfig,
|
||||
UserService,
|
||||
@@ -488,7 +488,7 @@ Furthermore, you may need to extend core services if you need to perform actions
|
||||
|
||||
Start by creating the file `src/services/permission.ts` with the following content:
|
||||
|
||||
```ts title=src/services/permission.ts
|
||||
```ts title="src/services/permission.ts"
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
import { Permission } from "../models/permission"
|
||||
import PermissionRepository from "../repositories/permission"
|
||||
@@ -533,7 +533,7 @@ Furthermore, you may need to extend core services if you need to perform actions
|
||||
|
||||
Next, create the file `src/services/user.ts` with the following content:
|
||||
|
||||
```ts title=src/services/user.ts
|
||||
```ts title="src/services/user.ts"
|
||||
import {
|
||||
UserService as MedusaUserService, User,
|
||||
} from "@medusajs/medusa"
|
||||
@@ -556,7 +556,7 @@ Furthermore, you may need to extend core services if you need to perform actions
|
||||
|
||||
Then, create the file `src/services/role.ts` with the following content:
|
||||
|
||||
```ts title=src/services/role.ts
|
||||
```ts title="src/services/role.ts"
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
import { Role } from "../models/role"
|
||||
import RoleRepository from "../repositories/role"
|
||||
@@ -661,7 +661,7 @@ Furthermore, you may need to extend core services if you need to perform actions
|
||||
|
||||
Start by creating the file `src/api/admin/roles/route.ts` with the following content:
|
||||
|
||||
```ts title=src/api/admin/roles/route.ts
|
||||
```ts title="src/api/admin/roles/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -697,7 +697,7 @@ Furthermore, you may need to extend core services if you need to perform actions
|
||||
|
||||
Next, create the file `src/api/routes/admin/roles/[id]/user/[user_id]/route.ts` with the following content:
|
||||
|
||||
```ts title=src/api/routes/admin/roles/[id]/user/[user_id]/route.ts
|
||||
```ts title="src/api/routes/admin/roles/[id]/user/[user_id]/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -37,7 +37,7 @@ To subscribe to an event, you must create a [subscriber](../../../development/ev
|
||||
|
||||
Create the file `src/subscribers/invite-created.ts` with the following content:
|
||||
|
||||
```ts title=src/subscribers/invite-created.ts
|
||||
```ts title="src/subscribers/invite-created.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -78,7 +78,7 @@ In this method, you should typically send an email to the user. You can place an
|
||||
|
||||
For example, you can implement this subscriber to send emails using SendGrid:
|
||||
|
||||
```ts title=src/subscribers/invite.ts
|
||||
```ts title="src/subscribers/invite.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -123,7 +123,7 @@ If the notification provider you’re using already implements the logic to hand
|
||||
|
||||
For example:
|
||||
|
||||
```ts title=src/loaders/customer-confirmation.ts
|
||||
```ts title="src/loaders/customer-confirmation.ts"
|
||||
import {
|
||||
MedusaContainer,
|
||||
NotificationService,
|
||||
|
||||
@@ -111,7 +111,7 @@ Where `<YOUR_SEGMENT_WRITE_KEY>` is the Write Key shown on the page of the Segme
|
||||
|
||||
Finally, in `medusa-config.js`, add the following new item to the `plugins` array:
|
||||
|
||||
```jsx title=medusa-config.js
|
||||
```jsx title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -155,7 +155,7 @@ In some cases, you might want to track more events or custom events. You can do
|
||||
|
||||
For example, you can add the following [subscriber](../../development/events/subscribers.mdx) to listen to the `customer.created` event and add tracking for every customer created:
|
||||
|
||||
```ts title=src/subscribers/customer.ts
|
||||
```ts title="src/subscribers/customer.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
|
||||
@@ -38,7 +38,7 @@ npm install medusa-plugin-contentful
|
||||
|
||||
Next, add the plugin into the `plugins` array in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -76,7 +76,7 @@ When the plugin syncs data between Contentful and Medusa, it expects a set of fi
|
||||
|
||||
For example, to change the name of the product’s `title` field, pass the following option to the plugin:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -168,7 +168,7 @@ npm install --save-dev contentful-migration
|
||||
|
||||
Create the file `src/loaders/contentful-migrations/product.ts` with the following content:
|
||||
|
||||
```ts title=src/loaders/contentful-migrations/product.ts
|
||||
```ts title="src/loaders/contentful-migrations/product.ts"
|
||||
import Migration, {
|
||||
MigrationContext,
|
||||
} from "contentful-migration"
|
||||
@@ -247,7 +247,7 @@ npm install --save-dev contentful-migration
|
||||
|
||||
Create the file `src/loaders/contentful-migrations/product-variant.ts` with the following content:
|
||||
|
||||
```ts title=src/loaders/contentful-migrations/product-variant.ts
|
||||
```ts title="src/loaders/contentful-migrations/product-variant.ts"
|
||||
import Migration, {
|
||||
MigrationContext,
|
||||
} from "contentful-migration"
|
||||
@@ -292,7 +292,7 @@ npm install --save-dev contentful-migration
|
||||
|
||||
Create the file `src/loaders/contentful-migrations/product-collection.ts` with the following content:
|
||||
|
||||
```ts title=src/loaders/contentful-migrations/product-collection.ts
|
||||
```ts title="src/loaders/contentful-migrations/product-collection.ts"
|
||||
import Migration, {
|
||||
MigrationContext,
|
||||
} from "contentful-migration"
|
||||
@@ -325,7 +325,7 @@ npm install --save-dev contentful-migration
|
||||
|
||||
Create the file `src/loaders/contentful-migrations/product-type.ts` with the following content:
|
||||
|
||||
```ts title=src/loaders/contentful-migrations/product-type.ts
|
||||
```ts title="src/loaders/contentful-migrations/product-type.ts"
|
||||
import Migration, {
|
||||
MigrationContext,
|
||||
} from "contentful-migration"
|
||||
@@ -358,7 +358,7 @@ npm install --save-dev contentful-migration
|
||||
|
||||
Create the file `src/loaders/contentful-migrations/region.ts` with the following content:
|
||||
|
||||
```ts title=src/loaders/contentful-migrations/region.ts
|
||||
```ts title="src/loaders/contentful-migrations/region.ts"
|
||||
import Migration, {
|
||||
MigrationContext,
|
||||
} from "contentful-migration"
|
||||
@@ -404,7 +404,7 @@ npm install --save-dev contentful-migration
|
||||
|
||||
Finally, create a [loader](../../development/loaders/overview.mdx) at `src/loaders/index.ts` with the following content:
|
||||
|
||||
```ts title=src/loaders/index.ts
|
||||
```ts title="src/loaders/index.ts"
|
||||
import {
|
||||
ConfigModule,
|
||||
StoreService,
|
||||
|
||||
@@ -146,7 +146,7 @@ Where:
|
||||
|
||||
Finally, open `medusa-config.js` and add the following new item to the `plugins` array:
|
||||
|
||||
```jsx title=medusa-config.js
|
||||
```jsx title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ npm install medusa-plugin-brightpearl
|
||||
|
||||
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ npm install @medusajs/file-local
|
||||
|
||||
Then, configure your `medusa-config.js` to include the plugin with the required options:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -80,7 +80,7 @@ If this configuration is not added, you’ll receive the error ["next/image Un-c
|
||||
|
||||
In `next.config.js` add the following option in the exported object:
|
||||
|
||||
```js title=next.config.js
|
||||
```js title="next.config.js"
|
||||
const { withStoreConfig } = require("./store-config")
|
||||
|
||||
// ...
|
||||
|
||||
@@ -92,7 +92,7 @@ Where `<ENDPOINT>` is the URL of your MinIO backend, `<BUCKET>` is the name of t
|
||||
|
||||
Finally, configure your `medusa-config.js` to include the plugin with the required options:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -147,7 +147,7 @@ MINIO_PRIVATE_BUCKET=exports
|
||||
|
||||
Then, add a new option to the plugin’s options in `medusa-config.js`:
|
||||
|
||||
```jsx title=medusa-config.js
|
||||
```jsx title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -175,7 +175,7 @@ Where `<YOUR_PRIVATE_ACCESS_KEY>` and `<YOUR_PRIVATE_SECRET_KEY>` are the access
|
||||
|
||||
Then, add two new options to the plugin’s options in `medusa-config.js`:
|
||||
|
||||
```jsx title=medusa-config.js
|
||||
```jsx title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -201,7 +201,7 @@ If this configuration is not added, you’ll receive the error ["next/image Un-c
|
||||
|
||||
In `next.config.js` add the following option in the exported object:
|
||||
|
||||
```jsx title=next.config.js
|
||||
```jsx title="next.config.js"
|
||||
const { withStoreConfig } = require("./store-config")
|
||||
|
||||
// ...
|
||||
|
||||
@@ -106,7 +106,7 @@ npm install medusa-file-s3
|
||||
|
||||
Then, in `medusa-config.js`, add to the `plugins` array the following new item:
|
||||
|
||||
```jsx title=medusa-config.js
|
||||
```jsx title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -164,7 +164,7 @@ You can pass additional AWS configurations, such as `customUserAgent`, in the pl
|
||||
|
||||
For example:
|
||||
|
||||
```jsx title=medusa-config.js
|
||||
```jsx title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -212,7 +212,7 @@ If this configuration is not added, you’ll receive the error ["next/image Un-c
|
||||
|
||||
In `next.config.js` add the following option in the exported object:
|
||||
|
||||
```jsx title=next.config.js
|
||||
```jsx title="next.config.js"
|
||||
const { withStoreConfig } = require("./store-config")
|
||||
|
||||
// ...
|
||||
|
||||
@@ -108,7 +108,7 @@ Where:
|
||||
|
||||
Finally, in `medusa-config.js` add a new item to the `plugins` array:
|
||||
|
||||
```jsx title=medusa-config.js
|
||||
```jsx title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -160,7 +160,7 @@ If this configuration is not added, you’ll receive the error ["next/image Un-
|
||||
|
||||
In `next.config.js` add the following option in the exported object:
|
||||
|
||||
```jsx title=next.config.js
|
||||
```jsx title="next.config.js"
|
||||
const { withStoreConfig } = require("./store-config")
|
||||
|
||||
// ...
|
||||
|
||||
@@ -30,7 +30,7 @@ npm install medusa-fulfillment-manual
|
||||
|
||||
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ npm install medusa-fulfillment-webshipper
|
||||
|
||||
Next, add the plugin to the `plugins` array in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@ Make sure to replace `<YOUR_API_KEY>` with your API Key and `<YOUR_NEWSLETTER_LI
|
||||
|
||||
Open `medusa-config.js` and add the new plugin into the `plugins` array:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...,
|
||||
{
|
||||
@@ -123,7 +123,7 @@ To subscribe users to the newsletter without using this API Route or at a specif
|
||||
|
||||
Here’s an example of using the `mailchimpService` in an API Route:
|
||||
|
||||
```ts title=src/api/store/subscribe/route.ts
|
||||
```ts title="src/api/store/subscribe/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -3943,7 +3943,7 @@ Where `<ORDER_PLACED_TEMPLATE_ID` is the ID of your template for order placed em
|
||||
|
||||
Finally, in your `medusa-config.js` file, add the SendGrid plugin into the array of plugins:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...,
|
||||
{
|
||||
@@ -4000,7 +4000,7 @@ You can resolve the SendGrid service to send emails from your custom services or
|
||||
|
||||
For example, in an API Route:
|
||||
|
||||
```ts title=src/api/store/email/route.ts
|
||||
```ts title="src/api/store/email/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -78,7 +78,7 @@ npm install medusa-plugin-slack-notification
|
||||
|
||||
After that, open `medusa-config.js` and add the new plugin with its configurations in the `plugins` array:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...,
|
||||
{
|
||||
|
||||
@@ -55,7 +55,7 @@ Make sure to replace `<YOUR_ACCOUNT_SID>`, `<YOUR_AUTH_TOKEN>`, and `<YOUR_TWILI
|
||||
|
||||
Finally, add the plugin and its options in the `medusa-config.js` file to the `plugins` array:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -85,7 +85,7 @@ For this example to work, you'll need to have an [event bus module](../../develo
|
||||
|
||||
Create the file `src/subscriber/sms.ts` in your Medusa backend with the following content:
|
||||
|
||||
```ts title=src/subscriber/sms.ts
|
||||
```ts title="src/subscriber/sms.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
|
||||
@@ -30,7 +30,7 @@ npm install medusa-plugin-discount-generator
|
||||
|
||||
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -65,7 +65,7 @@ The `DiscountGeneratorService` has one method `generateDiscount`. This method re
|
||||
|
||||
Here's an example of using the service in an API Route:
|
||||
|
||||
```ts title=src/api/store/generate-discount-code/route.ts
|
||||
```ts title="src/api/store/generate-discount-code/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -44,7 +44,7 @@ Where `<YOUR_ACCESS_KEY>` is your ipstack account’s access key. It’s availab
|
||||
|
||||
Finally, add the IP lookup plugin into the plugins array exported as part of the Medusa configuration in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// other plugins...
|
||||
{
|
||||
@@ -80,7 +80,7 @@ You can learn more about creating an API Route [here](../../development/api-rout
|
||||
|
||||
:::
|
||||
|
||||
```ts title=src/api/store/customer-region/route.ts
|
||||
```ts title="src/api/store/customer-region/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -124,7 +124,7 @@ For example, you can attach it to all `/store` routes to ensure the customer’s
|
||||
|
||||
<!-- eslint-disable @typescript-eslint/no-var-requires -->
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import type { MiddlewaresConfig } from "@medusajs/medusa"
|
||||
const { preCartCreation } = require(
|
||||
"medusa-plugin-ip-lookup/api/medusa-middleware"
|
||||
|
||||
@@ -44,7 +44,7 @@ npm install medusa-plugin-restock-notification
|
||||
|
||||
Then, add the plugin into the plugins array exported as part of the Medusa configuration in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// other plugins...
|
||||
{
|
||||
@@ -116,7 +116,7 @@ The SendGrid plugin already listens to and handles the `restock-notification.res
|
||||
|
||||
Here's an example of a [subscriber](../../development/events/subscribers.mdx) that listens to the `restock-notification.restocked` event and uses the [SendGrid plugin](../notifications/sendgrid.mdx) to send the subscribed customers an email:
|
||||
|
||||
```ts title=src/subscribers/restock-notification.ts
|
||||
```ts title="src/subscribers/restock-notification.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
|
||||
@@ -37,7 +37,7 @@ npm install medusa-plugin-wishlist
|
||||
|
||||
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
|
||||
@@ -64,7 +64,7 @@ Where:
|
||||
|
||||
Finally, in `medusa-config.js`, add the Klarna plugin to the `plugins` array with the necessary configurations:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// other plugins...
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@ Notice that during development it’s highly recommended to set `PAYPAL_SANDBOX`
|
||||
|
||||
Then, in `medusa-config.js`, add the PayPal plugin to the `plugins` array with the configurations necessary:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// other plugins...
|
||||
{
|
||||
@@ -138,7 +138,7 @@ Medusa has a Next.js Starter Template that you can easily use with your Medusa b
|
||||
|
||||
In your `.env.local` file (or the file you’re using for your environment variables), add the following variable:
|
||||
|
||||
```bash title=.env.local
|
||||
```bash title=".env.local"
|
||||
NEXT_PUBLIC_PAYPAL_CLIENT_ID=<YOUR_CLIENT_ID>
|
||||
```
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ Next, you need to add configurations for your stripe plugin.
|
||||
|
||||
In `medusa-config.js` add the following at the end of the `plugins` array:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -145,7 +145,7 @@ Medusa has a Next.js Starter Template that you can easily use with your Medusa b
|
||||
|
||||
In your `.env.local` file (or the file you’re using for your environment variables), add the following variable:
|
||||
|
||||
```bash title=.env.local
|
||||
```bash title=".env.local"
|
||||
NEXT_PUBLIC_STRIPE_KEY=<YOUR_PUBLISHABLE_KEY>
|
||||
```
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ Where `<YOUR_APP_ID>` and `<YOUR_ADMIN_API_KEY>` are respectively the Applicatio
|
||||
|
||||
Finally, in `medusa-config.js` add the following item into the `plugins` array:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -151,7 +151,7 @@ These settings are just examples of what you can pass to the Algolia provider. I
|
||||
|
||||
Here's an example of the settings you can use:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -243,7 +243,7 @@ The Next.js Starter Template has the Algolia integration available out of the bo
|
||||
|
||||
First, ensure that the search feature is enabled in `store.config.json`:
|
||||
|
||||
```json title=store.config.json
|
||||
```json title="store.config.json"
|
||||
{
|
||||
"features": {
|
||||
"search": true
|
||||
@@ -263,7 +263,7 @@ Where `<YOUR_APP_ID>` and `<YOUR_SEARCH_API_KEY>` are respectively the Applicati
|
||||
|
||||
Finally, change the code in `src/lib/search-client.ts` to the following:
|
||||
|
||||
```ts title=src/lib/search-client.ts
|
||||
```ts title="src/lib/search-client.ts"
|
||||
import algoliasearch from "algoliasearch/lite"
|
||||
|
||||
const appId = process.env.NEXT_PUBLIC_SEARCH_APP_ID || ""
|
||||
|
||||
@@ -52,7 +52,7 @@ Where `<YOUR_MEILISEARCH_HOST>` is the host of your MeiliSearch instance. By def
|
||||
|
||||
Finally, in `medusa-config.js` add the following item into the `plugins` array:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -76,7 +76,7 @@ const plugins = [
|
||||
|
||||
Under the `settings` key of the plugin's options, you can add settings specific to each index. The settings are of the following format:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -117,7 +117,7 @@ These settings are just examples of what you can pass to the MeiliSearch provide
|
||||
|
||||
Here's an example of the settings you can use:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
@@ -223,7 +223,7 @@ The Next.js Starter Template has the MeiliSearch integration available out of th
|
||||
|
||||
First, ensure that the search feature is enabled in `store.config.json`:
|
||||
|
||||
```json title=store.config.json
|
||||
```json title="store.config.json"
|
||||
{
|
||||
"features": {
|
||||
"search": true
|
||||
|
||||
@@ -63,7 +63,7 @@ Where:
|
||||
|
||||
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
const plugins = [
|
||||
// ...,
|
||||
{
|
||||
|
||||
@@ -271,7 +271,7 @@ Medusa allows you to create custom API Routes exposed as REST APIs.
|
||||
|
||||
For example, create the following API Route that allows you to check the customer’s group and whether it has the `is_b2b` flag enabled:
|
||||
|
||||
```ts title=src/api/store/customers/is-b2b/route.ts
|
||||
```ts title="src/api/store/customers/is-b2b/route.ts"
|
||||
import type {
|
||||
CustomerService,
|
||||
MedusaRequest,
|
||||
@@ -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:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import {
|
||||
requireCustomerAuthentication,
|
||||
type MiddlewaresConfig,
|
||||
|
||||
@@ -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:
|
||||
|
||||
```ts title=src/subscribers/add-custom-to-vip.ts
|
||||
```ts title="src/subscribers/add-custom-to-vip.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -520,7 +520,7 @@ You can alternatively have a Scheduled Job that checks if the number of new prod
|
||||
|
||||
Here’s an example of listening to the `product.created` event in a subscriber and send a newsletter if the condition is met:
|
||||
|
||||
```ts title=src/subscribers/send-products-newsletter.ts
|
||||
```ts title="src/subscribers/send-products-newsletter.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
|
||||
@@ -142,7 +142,7 @@ For example, if you're selling the Harry Potter movies, you would have a `Produc
|
||||
|
||||
To do that, create the file `src/models/product-media.ts` with the following content:
|
||||
|
||||
```ts title=src/models/product-media.ts
|
||||
```ts title="src/models/product-media.ts"
|
||||
import {
|
||||
BeforeInsert,
|
||||
Column,
|
||||
@@ -272,7 +272,7 @@ Creating an API Route also requires creating a service, which is a class that ty
|
||||
|
||||
Before creating the API Routes, you’ll create the `ProductMediaService`. Create the file `src/services/product-media.ts` with the following content:
|
||||
|
||||
```ts title=src/services/product-media.ts
|
||||
```ts title="src/services/product-media.ts"
|
||||
import {
|
||||
FindConfig,
|
||||
ProductVariantService,
|
||||
@@ -454,7 +454,7 @@ Creating an API Route also requires creating a service, which is a class that ty
|
||||
|
||||
You can now create the API Routes. Create the file `src/api/admin/product-media/route.ts` with the following content:
|
||||
|
||||
```ts title=src/api/admin/product-media/route.ts
|
||||
```ts title="src/api/admin/product-media/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -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:
|
||||
|
||||
```tsx title=src/admin/routes/product-media/page.tsx
|
||||
```tsx title="src/admin/routes/product-media/page.tsx"
|
||||
import { RouteConfig } from "@medusajs/admin"
|
||||
import { DocumentText } from "@medusajs/icons"
|
||||
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:
|
||||
|
||||
```tsx title=src/admin/components/product-media/CreateForm/index.tsx
|
||||
```tsx title="src/admin/components/product-media/CreateForm/index.tsx"
|
||||
import { useState } from "react"
|
||||
import { MediaType } from "../../../../models/product-media"
|
||||
import {
|
||||
@@ -952,7 +952,7 @@ Finally, you can send a notification, such as an email, to the customer using th
|
||||
|
||||
Here’s an example of a subscriber that retrieves the download links and sends them to the customer using the SendGrid plugin:
|
||||
|
||||
```ts title=src/subscribers/handle-order.ts
|
||||
```ts title="src/subscribers/handle-order.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
@@ -1055,7 +1055,7 @@ To implement this, create a storefront API Route that allows you to fetch the di
|
||||
|
||||
Create the file `src/api/store/product-media/route.ts` with the following content:
|
||||
|
||||
```ts title=src/api/store/product-media/route.ts
|
||||
```ts title="src/api/store/product-media/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -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:
|
||||
|
||||
```ts title=src/app/api/download/preview/route.ts
|
||||
```ts title="src/app/api/download/preview/route.ts"
|
||||
import { NextRequest, NextResponse } from "next/server"
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
@@ -1208,7 +1208,7 @@ To implement this, create a storefront API Route that allows you to fetch the di
|
||||
|
||||
Next, create the preview button in the file `src/modules/products/components/product-media-preview/index.tsx`:
|
||||
|
||||
```tsx title=src/modules/products/components/product-media-preview/index.tsx
|
||||
```tsx title="src/modules/products/components/product-media-preview/index.tsx"
|
||||
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:
|
||||
|
||||
```tsx title=src/modules/products/components/product-actions/index.tsx
|
||||
```tsx title="src/modules/products/components/product-actions/index.tsx"
|
||||
// other imports...
|
||||
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:
|
||||
|
||||
```tsx title=src/modules/products/components/product-tabs/index.tsx
|
||||
```tsx title="src/modules/products/components/product-tabs/index.tsx"
|
||||
const ProductTabs = ({ product }: ProductTabsProps) => {
|
||||
const tabs = useMemo(() => {
|
||||
return [
|
||||
@@ -1426,7 +1426,7 @@ When a customer purchases a digital product, the shipping form shown during chec
|
||||
|
||||
<!-- eslint-skip -->
|
||||
|
||||
```tsx title=src/lib/context/checkout-context.tsx
|
||||
```tsx title="src/lib/context/checkout-context.tsx"
|
||||
"use client"
|
||||
|
||||
import { medusaClient } from "@lib/config"
|
||||
@@ -1877,7 +1877,7 @@ When a customer purchases a digital product, the shipping form shown during chec
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/modules/checkout/components/addresses/index.tsx
|
||||
```tsx title="src/modules/checkout/components/addresses/index.tsx"
|
||||
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:
|
||||
|
||||
```tsx title=src/modules/order/components/shipping-details/index.tsx
|
||||
```tsx title="src/modules/order/components/shipping-details/index.tsx"
|
||||
import { Address, ShippingMethod } from "@medusajs/medusa"
|
||||
|
||||
type ShippingDetailsProps = {
|
||||
@@ -2011,7 +2011,7 @@ After the customer purchases the digital product you can show a download button
|
||||
|
||||
Create the file `src/api/store/product-media/download/[variant_id]/route.ts` with the following content:
|
||||
|
||||
```ts title=src/api/store/product-media/download/route.ts
|
||||
```ts title="src/api/store/product-media/download/route.ts"
|
||||
import type {
|
||||
AbstractFileService,
|
||||
MedusaRequest,
|
||||
@@ -2082,7 +2082,7 @@ After the customer purchases the digital product you can show a download button
|
||||
|
||||
Then, add the `requireCustomerAuthentication` middleware to this API Route in `src/api/middlewares.ts`:
|
||||
|
||||
```ts title=src/api/middlewares.ts
|
||||
```ts title="src/api/middlewares.ts"
|
||||
import {
|
||||
requireCustomerAuthentication,
|
||||
type MiddlewaresConfig,
|
||||
@@ -2104,7 +2104,7 @@ After the customer purchases the digital product you can show a download button
|
||||
|
||||
To mask the presigned URL, create a Next.js API route at `src/app/api/download/main/[variant_id]/route.ts` with the following content:
|
||||
|
||||
```ts title=src/app/api/download/main/[variant_id]/route.ts
|
||||
```ts title="src/app/api/download/main/[variant_id]/route.ts"
|
||||
import { NextRequest, NextResponse } from "next/server"
|
||||
|
||||
export async function GET(
|
||||
@@ -2173,7 +2173,7 @@ After the customer purchases the digital product you can show a download button
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
|
||||
```tsx title=src/modules/order/components/items/index.tsx
|
||||
```tsx title="src/modules/order/components/items/index.tsx"
|
||||
import useEnrichedLineItems from "@lib/hooks/use-enrich-line-items"
|
||||
import { LineItem, Region } from "@medusajs/medusa"
|
||||
import LineItemOptions from "@modules/common/components/line-item-options"
|
||||
|
||||
@@ -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:
|
||||
|
||||
```ts title=src/migrations/<TIMESTAMP>_add-user-store-id.ts
|
||||
```ts title="src/migrations/<TIMESTAMP>_add-user-store-id.ts"
|
||||
// ...
|
||||
|
||||
export class AddUserStoreId1681287255173
|
||||
@@ -188,7 +188,7 @@ You can also extend services if you need to customize a functionality implemente
|
||||
|
||||
<!-- eslint-disable prefer-rest-params -->
|
||||
|
||||
```ts title=src/services/user.ts
|
||||
```ts title="src/services/user.ts"
|
||||
import { Lifetime } from "awilix"
|
||||
import {
|
||||
UserService as MedusaUserService,
|
||||
@@ -273,7 +273,7 @@ To listen to events, you need to create Subscribers that subscribe a handler fun
|
||||
|
||||
To listen to the `order.placed` event, create the file `src/subscribers/orderNotifier.ts` with the following content:
|
||||
|
||||
```ts title=src/subscribers/orderNotifier.ts
|
||||
```ts title="src/subscribers/orderNotifier.ts"
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
|
||||
@@ -99,7 +99,7 @@ To search through product variants by their barcode, you can create a custom API
|
||||
|
||||
Here’s an example of creating a custom API Route at `/store/pos/search-barcode` that searches product variants by a barcode:
|
||||
|
||||
```ts title=src/api/store/pos/search-barcode/route.ts
|
||||
```ts title="src/api/store/pos/search-barcode/route.ts"
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
|
||||
@@ -172,7 +172,7 @@ To enable the Product Module, first, make sure to set the following environment
|
||||
|
||||
Then, enable the `productModule` feature flag in `store.config.json`:
|
||||
|
||||
```json title=store.config.json
|
||||
```json title="store.config.json"
|
||||
{
|
||||
"features": {
|
||||
// other features...
|
||||
@@ -198,7 +198,7 @@ The Next.js Starter Storefront by default is compatible with MeiliSearch.
|
||||
|
||||
To enable or disable the search engine, change the value of the feature in `store.config.json`:
|
||||
|
||||
```json title=store.config.json
|
||||
```json title="store.config.json"
|
||||
{
|
||||
"features": {
|
||||
"search": false
|
||||
@@ -269,7 +269,7 @@ Where `<YOUR_APP_ID>` and `<YOUR_SEARCH_API_KEY>` are the Algolia App ID and Alg
|
||||
|
||||
Next, change the content of `src/lib/search-client.ts` to the following:
|
||||
|
||||
```ts title=src/lib/search-client.ts
|
||||
```ts title="src/lib/search-client.ts"
|
||||
import algoliasearch from "algoliasearch/lite"
|
||||
|
||||
const appId = process.env.NEXT_PUBLIC_SEARCH_APP_ID || ""
|
||||
|
||||
@@ -12,7 +12,7 @@ In your `medusa-config.js` , you should ensure that you've configured your CORS
|
||||
|
||||
The default configuration uses the following CORS settings:
|
||||
|
||||
```js title=medusa-config.js
|
||||
```js title="medusa-config.js"
|
||||
// CORS when consuming Medusa from admin
|
||||
const ADMIN_CORS = process.env.ADMIN_CORS ||
|
||||
"http://localhost:7000,http://localhost:7001"
|
||||
|
||||
@@ -24,4 +24,4 @@ As a last resort to resolve your issue, please try to clear your `npx` cache, as
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
If your issue persists, please try to search through [our GitHub issues](https://github.com/medusajs/medusa/issues) to see if there's a solution for your issue. If not, please [create an issue on GitHub](https://github.com/medusajs/medusa/issues/new?assignees=olivermrbl&labels=status:+needs+triaging,+type:+bug&template=bug_report.md&title=) and our team will help you resolve it soon.
|
||||
If your issue persists, please try to search through [our GitHub issues](https://github.com/medusajs/medusa/issues) to see if there's a solution for your issue. If not, please [create an issue on GitHub](https://github.com/medusajs/medusa/issues/new?assignees=olivermrbl&labels=status:+needs+triaging,+type:+bug&template=bug_report.md&title=") and our team will help you resolve it soon."
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user