chore: reorganize docs apps (#7228)

* reorganize docs apps

* add README

* fix directory

* add condition for old docs
This commit is contained in:
Shahed Nasser
2024-05-03 17:36:38 +03:00
committed by GitHub
parent 224ebb2154
commit 4fe28f5a95
6187 changed files with 601447 additions and 598226 deletions
@@ -0,0 +1,301 @@
import { CodeTabs, CodeTab } from "docs-ui"
export const metadata = {
title: `Examples of the Sales Channel Module`,
}
# {metadata.title}
In this guide, youll find common examples of how you can use the Sales Channel Module in your application.
## Create a Sales Channel
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
import { ISalesChannelModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
export async function POST(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const salesChannelModuleService: ISalesChannelModuleService =
request.scope.resolve(ModuleRegistrationName.SALES_CHANNEL)
const salesChannel = await salesChannelModuleService.create({
name: request.body.name,
})
res.json({
sales_channel: salesChannel,
})
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import {
initialize as initializeSalesChannelModule,
} from "@medusajs/sales-channel"
export async function POST(request: Request) {
const salesChannelModuleService =
await initializeSalesChannelModule()
const body = await request.json()
const salesChannel = await salesChannelModuleService.create({
name: body.name,
})
return NextResponse.json({ sales_channel: salesChannel })
}
```
</CodeTab>
</CodeTabs>
---
## List Sales Channels
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
import { ISalesChannelModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
export async function GET(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const salesChannelModuleService: ISalesChannelModuleService =
request.scope.resolve(ModuleRegistrationName.SALES_CHANNEL)
res.json({
sales_channels: salesChannelModuleService.list(),
})
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import {
initialize as initializeSalesChannelModule,
} from "@medusajs/sales-channel"
export async function GET(request: Request) {
const salesChannelModuleService =
await initializeSalesChannelModule()
const salesChannels = await salesChannelModuleService.list()
return NextResponse.json({ sales_channels: salesChannels })
}
```
</CodeTab>
</CodeTabs>
---
## Retrieve a Sales Channel by its ID
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
import { ISalesChannelModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
export async function GET(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const salesChannelModuleService: ISalesChannelModuleService =
request.scope.resolve(ModuleRegistrationName.SALES_CHANNEL)
const salesChannel = await salesChannelModuleService.retrieve(
request.params.id
)
res.json({
sales_channel: salesChannel,
})
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import {
initialize as initializeSalesChannelModule,
} from "@medusajs/sales-channel"
type ContextType = {
params: {
id: string
}
}
export async function GET(
request: Request,
{ params }: ContextType
) {
const salesChannelModuleService =
await initializeSalesChannelModule()
const body = await request.json()
const salesChannel = await salesChannelModuleService.retrieve(
params.id
)
return NextResponse.json({ sales_channel: salesChannel })
}
```
</CodeTab>
</CodeTabs>
---
## Update a Sales Channel
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
import { ISalesChannelModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
export async function POST(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const salesChannelModuleService: ISalesChannelModuleService =
request.scope.resolve(ModuleRegistrationName.SALES_CHANNEL)
const salesChannel = await salesChannelModuleService.update({
id: request.params.id,
description: request.body.description,
})
res.json({
sales_channel: salesChannel,
})
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import {
initialize as initializeSalesChannelModule,
} from "@medusajs/sales-channel"
type ContextType = {
params: {
id: string
}
}
export async function POST(
request: Request,
{ params }: ContextType
) {
const salesChannelModuleService =
await initializeSalesChannelModule()
const body = await request.json()
const salesChannel = await salesChannelModuleService.update({
id: params.id,
description: body.description,
})
return NextResponse.json({ sales_channel: salesChannel })
}
```
</CodeTab>
</CodeTabs>
---
## Delete a Sales Channel
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
import { ISalesChannelModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
export async function DELETE(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const salesChannelModuleService: ISalesChannelModuleService =
request.scope.resolve(ModuleRegistrationName.SALES_CHANNEL)
await salesChannelModuleService.delete(request.params.id)
res.status(200)
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import {
initialize as initializeSalesChannelModule,
} from "@medusajs/sales-channel"
type ContextType = {
params: {
id: string
}
}
export async function DELETE(
request: Request,
{ params }: ContextType
) {
const salesChannelModuleService =
await initializeSalesChannelModule()
await salesChannelModuleService.delete(params.id)
}
```
</CodeTab>
</CodeTabs>
---
## More Examples
The [Sales Channel Module interface reference](/references/sales-channel) provides a reference to all the methods available for use with examples for each.
@@ -0,0 +1,134 @@
import { CodeTabs, CodeTab } from "docs-ui"
export const metadata = {
title: `Sales Channel Module`,
}
# {metadata.title}
The Sales Channel Module is the `@medusajs/sales-channel` NPM package that provides sales-channel-related features in your Medusa and Node.js applications.
## What's a Sales Channel?
A sales channel indicates an online or offline platform that you sell products on.
Some use case examples for using a sales channel:
- Implement a B2B Ecommerce Store.
- Specify different products for each channel you sell in.
- Support Omnichannel in your ecommerce store.
---
## Features
### Sales Channel Management
Store and manage sales channels in your store.
Each sales channel has different meta information such as name or description, allowing you to easily differentiate between sales channels.
```ts
const salesChannels = await salesChannelModuleService.create([
{
name: "B2B",
},
{
name: "Mobile App",
},
])
```
### Product Availability
By combining the Product and Sales Channel modules, you can specify a product's availability per sales channel.
For example, B2B customers viewing products only see products in the B2B sales channel.
### Cart and Order Scoping
Carts, available through the Cart Module, are scoped to a sales channel. Paired with the product availability feature, you benefit from more features like allowing only products available in sales channel in a cart.
Orders are also scoped to a sales channel due to the relation between the Sales Channel and Order modules.
---
## Configure Sales Channel Module
After installing the `@medusajs/sales-channel` package in your Medusa application, add it to the `modules` object in `medusa-config.js`:
```js title="medusa-config.js"
const modules = {
// ...
salesChannel: {
resolve: "@medusajs/sales-channel",
},
}
```
---
## How to Use Sales Channel Module's Service
You can use the Sales Channel Module's main service by resolving from the Medusa container the resource `ModuleRegistrationName.SALES_CHANNEL` imported from `@medusajs/modules-sdk`.
For example:
<CodeTabs groupId="resource-type">
<CodeTab label="API Route" value="api-route">
```ts title="src/api/store/custom/route.ts"
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"
import { ISalesChannelModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
export async function GET(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const salesChannelModuleService: ISalesChannelModuleService =
request.scope.resolve(ModuleRegistrationName.SALES_CHANNEL)
res.json({
sales_channels: await salesChannelModuleService.list(),
})
}
```
</CodeTab>
<CodeTab label="Subscriber" value="subscribers">
```ts title="src/subscribers/custom-handler.ts"
import { SubscriberArgs } from "@medusajs/medusa"
import { ISalesChannelModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
export default async function subscriberHandler({
container,
}: SubscriberArgs) {
const salesChannelModuleService: ISalesChannelModuleService =
container.resolve(ModuleRegistrationName.SALES_CHANNEL)
const salesChannels = await salesChannelModuleService.list()
}
```
</CodeTab>
<CodeTab label="Workflow Step" value="workflow-step">
```ts title="src/workflows/hello-world/step1.ts"
import { createStep } from "@medusajs/workflows-sdk"
import { ISalesChannelModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
const step1 = createStep("step-1", async (_, context) => {
const salesChannelModuleService: ISalesChannelModuleService =
context.container.resolve(
ModuleRegistrationName.SALES_CHANNEL
)
const salesChannels = await salesChannelModuleService.list()
})
```
</CodeTab>
</CodeTabs>
@@ -0,0 +1,78 @@
import { CodeTabs, CodeTab } from "docs-ui"
export const metadata = {
title: `Publishable API Keys with Sales Channels`,
}
# {metadata.title}
In this document, youll learn what publishable API keys are and how to use them with sales channels.
## Without Publishable API Keys
When using multiple sales channels, youll need to specify the ID of a storefronts sales channel. This ensures that you retrieve the products available in that sales channel and associate the sales channel with the storefronts carts and orders.
The Store API routes accept the sales channels IDs differently. For example, the [List Products API route](https://docs.medusajs.com/api/store#products) accepts the sales channels ID as a query parameter, whereas the [Create Cart API route](https://docs.medusajs.com/api/store#carts_postcart) accepts it in the requests body.
This approach is tedious and error-prone as your storefront scales and as you develop multiple types of storefronts.
---
## Introducing Publishable API Keys
The API Key module allows you to create keys for different usages. One of those usages is to create a publishable API key.
A publishable API key is a client key scoped to one or more sales channels. When passed in the header of a request, the Medusa application infers the associated sales channels.
So, instead of the previous approach of manually passing the sales channels ID based on the API route, you always pass the publishable API key in the header of your requests:
```bash
curl http://localhost:9000/store/products \
x-publishable-api-key: {your_publishable_api_key}
```
The Medusa JS Client and Medusa React both provide the option to pass the publishable API key during initialization:
<CodeTabs groupId="client-id">
<CodeTab label="JS Client" value="js-client">
```ts
const medusa = new Medusa({
maxRetries: 3,
baseUrl: "http://localhost:9000",
publishableApiKey,
})
```
</CodeTab>
<CodeTab label="Medusa React" value="medusa-react">
```tsx
import { MedusaProvider } from "medusa-react"
// define query client...
const App = () => {
return (
<MedusaProvider
queryClientProviderProps={{ client: queryClient }}
baseUrl="http://localhost:9000"
// ...
publishableApiKey={publishableApiKey}
>
<MyStorefront />
</MedusaProvider>
)
}
```
</CodeTab>
</CodeTabs>
Then, all requests using the client/hooks automatically include the publishable API key in the header.
---
## How to Create a Publishable API Key?
To create a publishable API key, either use the Medusa Admin or the [Admin API Routes](https://docs.medusajs.com/api/admin#publishable-api-keys).
@@ -0,0 +1,49 @@
export const metadata = {
title: `Relations between Sales Channel Module and Other Modules`,
}
# {metadata.title}
When Commerce Modules are used together in a Medusa application, the Medusa application handles building the relations between these modules.
This document showcases the relation between the Sales Channel Module and other Commerce Modules.
## Product Module
A product has different availability for different sales channels. The Medusa application forms a relation between the `Product` and the `SalesChannel` data models.
A product can be available in more than one sales channel. Then, you can retrieve only the products of a sales channel.
![A diagram showcasing an example of how resources from the Sales Channel and Product modules are linked](https://res.cloudinary.com/dza7lstvk/image/upload/v1709809833/Medusa%20Resources/product-sales-channel_ciqj6i.jpg)
---
## Cart Module
A cart is associated with the sales channel it's created in. The Medusa application forms a relation between the `Cart` and the `SalesChannel` data models.
![A diagram showcasing an example of how resources from the Sales Channel and Cart modules are linked](https://res.cloudinary.com/dza7lstvk/image/upload/v1709811093/Medusa%20Resources/sales-channel-cart_m0hozt.jpg)
For example, if a customer adds an item to the cart in a mobile app, the cart is associated with the mobile app's sales channel. However, if a customer adds an item to the cart in a web storefront, the cart is associated with the storefront's sales channel.
---
## Order Module
An order is associated with the sales channel it's created in. The Medusa application forms a relation between the `Order` and the `SalesChannel` data models.
![A diagram showcasing an example of how resources from the Sales Channel and Order modules are linked](https://res.cloudinary.com/dza7lstvk/image/upload/v1709810401/Medusa%20Resources/sales-channel-order_ixayla.jpg)
For example, if an order is created in a mobile app, it'll be associated with its sales channel. If another order is created through a POS system, it'll be associated with the POS's sales channel.
---
## API Key Module
A publishable API key allows you to easily specify the sales channel scope in a client request. The Medusa application forms a relation between the `ApiKey` and the `SalesChannel` data models.
![A diagram showcasing an example of how resources from the Sales Channel and API Key modules are linked](https://res.cloudinary.com/dza7lstvk/image/upload/v1709812064/Medusa%20Resources/sales-channel-api-key_zmqi2l.jpg)
Using the API Key Module, you create a publishable key and associate it with a sales channel.
Instead of passing the sales channel's ID in every request either in the query or body parameters, you always pass the API key in the header of your requests. The Medusa application then infers the sales channel scope from it.