docs: create docs workspace (#5174)

* docs: migrate ui docs to docs universe

* created yarn workspace

* added eslint and tsconfig configurations

* fix eslint configurations

* fixed eslint configurations

* shared tailwind configurations

* added shared ui package

* added more shared components

* migrating more components

* made details components shared

* move InlineCode component

* moved InputText

* moved Loading component

* Moved Modal component

* moved Select components

* Moved Tooltip component

* moved Search components

* moved ColorMode provider

* Moved Notification components and providers

* used icons package

* use UI colors in api-reference

* moved Navbar component

* used Navbar and Search in UI docs

* added Feedback to UI docs

* general enhancements

* fix color mode

* added copy colors file from ui-preset

* added features and enhancements to UI docs

* move Sidebar component and provider

* general fixes and preparations for deployment

* update docusaurus version

* adjusted versions

* fix output directory

* remove rootDirectory property

* fix yarn.lock

* moved code component

* added vale for all docs MD and MDX

* fix tests

* fix vale error

* fix deployment errors

* change ignore commands

* add output directory

* fix docs test

* general fixes

* content fixes

* fix announcement script

* added changeset

* fix vale checks

* added nofilter option

* fix vale error
This commit is contained in:
Shahed Nasser authored and GitHub committed 2023-09-21 20:57:15 +03:00
1 parent 19c5d5ba36
commit fa7c94b4cc
3209 files changed
+32188 -31018

No files matched your search

@@ -0,0 +1,799 @@
---
description: 'Learn how to implement sales channels features for admins in Medusa using the REST APIs. This includes how to list sales channels, and create, retrieve, update and delete a sales channel. This also includes how to manage products in a sales channel.'
addHowToData: true
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# How to Manage Sales Channels
In this document, you’ll learn how to manage sales channels and their products and orders using the Admin APIs.
:::note
If you’re looking to learn more in-depth about what Sales Channels are and how they work, check out [this documentation](../sales-channels.md) instead.
:::
## Overview
Using Medusa’s Admin APIs, you can manage Sales Channels including creating, retrieving, updating, and deleting sales channels. You can also manage their products and orders.
This guide explains how to perform all these operations using the Admin APIs.
---
## Prerequisites
### Medusa Components
It's assumed that you already have a Medusa backend installed and set up. If not, you can follow our [quickstart guide](../../../development/backend/install.mdx) to get started.
### JS Client
This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client installed](../../../js-client/overview.md) and [have created an instance of the client](../../../js-client/overview.md#configuration).
### Medusa React
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.mdx) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.mdx#usage).
### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in this guide.
You can learn more about [authenticating as an admin user in the API reference](https://docs.medusajs.com/api/admin#authentication).
---
## Create Sales Channels
You can create a sales channel by sending a request to the Create a Sales Channel endpoint:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.create({
name: "App",
description: "Mobile app",
})
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateSalesChannel } from "medusa-react"
const CreateSalesChannel = () => {
const createSalesChannel = useAdminCreateSalesChannel()
// ...
const handleCreate = (name: string, description: string) => {
createSalesChannel.mutate({
name,
description,
})
}
// ...
}
export default CreateSalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "App",
description: "Mobile app",
}),
})
.then((response) => response.json())
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X POST '<BACKEND_URL>/admin/sales-channels' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
name: 'App',
description: 'Mobile app'
}'
```
</TabItem>
</Tabs>
This request requires the request body parameters `name`, and optionally accepts the `description` and `is_disabled` request body parameters.
It returns the created sales channel.
---
## List Sales Channels
You can list all sales channels by sending a request to the List Sales Channels endpoint:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.list()
.then(({ sales_channels, limit, offset, count }) => {
console.log(sales_channels.length)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { SalesChannel } from "@medusajs/medusa"
import { useAdminSalesChannels } from "medusa-react"
const SalesChannels = () => {
const { sales_channels, isLoading } = useAdminSalesChannels()
return (
<div>
{isLoading && <span>Loading...</span>}
{sales_channels && !sales_channels.length && (
<span>No Sales Channels</span>
)}
{sales_channels && sales_channels.length > 0 && (
<ul>
{sales_channels.map((salesChannel: SalesChannel) => (
<li key={salesChannel.id}>{salesChannel.name}</li>
))}
</ul>
)}
</div>
)
}
export default SalesChannels
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels`, {
credentials: "include",
})
.then((response) => response.json())
.then(({ sales_channels, limit, offset, count }) => {
console.log(sales_channels.length)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X GET '<BACKEND_URL>/admin/sales-channels' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
This request returns an array of all sales channels in your store. You can also pass query parameters to filter or customize the pagination of the results. Check out [the API Reference for a full list of query parameters.](https://docs.medusajs.com/api/admin#sales-channels_getsaleschannels)
---
## Retrieve a Sales Channel
You can retrieve a sales channel’s details by its ID using the Get Sales Channel endpoint:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.retrieve(salesChannelId)
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminSalesChannel } from "medusa-react"
const SalesChannel = () => {
const {
sales_channel,
isLoading,
} = useAdminSalesChannel(salesChannelId)
return (
<div>
{isLoading && <span>Loading...</span>}
{sales_channel && <span>{sales_channel.name}</span>}
</div>
)
}
export default SalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels/${salesChannelId}`, {
credentials: "include",
})
.then((response) => response.json())
.then(({ sales_channels, limit, offset, count }) => {
console.log(sales_channels.length)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X GET '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
This request returns the sales channel with the specified ID.
---
## Update a Sales Channel
You can update a Sales Channel’s details and attributes by sending a request to the Update Sales Channel endpoint:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.update(salesChannelId, {
is_disabled: false,
})
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUpdateSalesChannel } from "medusa-react"
const UpdateSalesChannel = () => {
const updateSalesChannel = useAdminUpdateSalesChannel(
salesChannelId
)
// ...
const handleUpdate = () => {
updateSalesChannel.mutate({
is_disabled: false,
})
}
// ...
}
export default UpdateSalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels/${salesChannelId}`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
is_disabled: false,
}),
})
.then((response) => response.json())
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X POST '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"is_disabled": false
}'
```
</TabItem>
</Tabs>
In this example, you enable a sales channel by changing the value of the `is_disabled` attribute.
This request returns the updated sales channel.
You can check out [the API Reference for a full list of body parameters](https://docs.medusajs.com/api/admin#sales-channels_postsaleschannelssaleschannel) that you can pass to this request.
---
## Delete a Sales Channel
You can delete a sales channel by sending a request to the Delete Sales Channel endpoint with the ID of the sales channel to delete:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.delete(salesChannelId)
.then(({ id, object, deleted }) => {
console.log(id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeleteSalesChannel } from "medusa-react"
const SalesChannel = () => {
const deleteSalesChannel = useAdminDeleteSalesChannel(
salesChannelId
)
// ...
const handleDelete = () => {
deleteSalesChannel.mutate()
}
// ...
}
export default SalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels/${salesChannelId}`, {
method: "DELETE",
credentials: "include",
})
.then((response) => response.json())
.then(({ id, object, deleted }) => {
console.log(id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X DELETE '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
The ID of the deleted sales channel is returned in the response.
---
## Manage Products
### Add Product to a Sales Channel
To add a product to a sales channel, send a request to the Sales Channel’s Add Products endpoint:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.addProducts(salesChannelId, {
product_ids: [
{
id: productId,
},
],
})
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminAddProductsToSalesChannel } from "medusa-react"
const SalesChannel = () => {
const addProducts = useAdminAddProductsToSalesChannel(
salesChannelId
)
// ...
const handleAddProducts = (productId: string) => {
addProducts.mutate({
product_ids: [
{
id: productId,
},
],
})
}
// ...
}
export default SalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(
`<BACKEND_URL>/admin/sales-channels/${salesChannelId}/products/batch`,
{
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
product_ids: [
{
id: productId,
},
],
}),
}
)
.then((response) => response.json())
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X POST '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"product_ids": [
{
"id": "<PRODUCT_ID>"
}
]
}'
```
</TabItem>
</Tabs>
This request accepts the `product_ids` body parameter, which is an array of objects. Each object in the array must have an `id` property with the ID of the product to add as a value.
This request returns the sales channel.
### List Products Available in a Sales Channel
You can list the products available in a sales channel by sending a request to the List Products endpoint and passing the `sales_channel_id` query parameter to filter by a specific sales channel:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.products.list({
sales_channel_id: [
salesChannelId,
],
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Product } from "@medusajs/medusa"
import {
PricedProduct,
} from "@medusajs/medusa/dist/types/pricing"
import { useAdminProducts } from "medusa-react"
const SalesChannelProducts = () => {
const { products, isLoading } = useAdminProducts({
sales_channel_id: [salesChannelId],
})
return (
<div>
{isLoading && <span>Loading...</span>}
{products && products.length > 0 && (
<ul>
{products.map(
(product: (Product | PricedProduct)) => (
<li key={product.id}>{product.title}</li>
)
)}
</ul>
)}
{products && !products.length && (
<span>No Products</span>
)}
</div>
)
}
export default SalesChannelProducts
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(
`<BACKEND_URL>/admin/products?sales_channel_id[0]=${salesChannelId}`,
{
credentials: "include",
}
)
.then((response) => response.json())
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X GET '<BACKEND_URL>/admin/products?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
The request returns an array of products that are available in the specified sales channel.
### Delete Products from a Sales Channel
:::info
Deleting a product from a sales channel doesn't delete it completely. It only makes it unavailable in that sales channel.
:::
You can delete a product from a sales channel by sending a request to the Sales Channel’s Delete Products endpoint:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
<!-- eslint-disable max-len -->
```ts
medusa.admin.salesChannels.removeProducts(salesChannelId, {
product_ids: [
{
id: productId,
},
],
})
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import {
useAdminDeleteProductsFromSalesChannel,
} from "medusa-react"
const SalesChannel = () => {
const deleteProducts = useAdminDeleteProductsFromSalesChannel(
salesChannelId
)
// ...
const handleDeleteProducts = (productId: string) => {
deleteProducts.mutate({
product_ids: [
{
id: productId,
},
],
})
}
// ...
}
export default SalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(
`<BACKEND_URL>/admin/sales-channels/${salesChannelId}/products/batch`,
{
method: "DELETE",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
product_ids: [
{
id: productId,
},
],
}),
}
)
.then((response) => response.json())
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X DELETE '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"product_ids": [
{
"id": "<PRODUCT_ID>"
}
]
}'
```
</TabItem>
</Tabs>
This request accepts the `product_ids` body parameter, which is an array of objects. Each object in the array must have an `id` property with the ID of the product to delete as a value.
This request returns the sales channel.
---
## List Orders by Sales Channels
You can filter orders by a specific sales channel by sending a request to the List Orders endpoint and passing the `sales_channel_id` query parameter to filter by a specific sales channel:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.orders.list({
sales_channel_id: [
salesChannelId,
],
limit: 50,
offset: 0,
})
.then(({ orders, limit, offset, count }) => {
console.log(orders.length)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Order } from "@medusajs/medusa"
import { useAdminOrders } from "medusa-react"
const SalesChannelOrders = () => {
const { orders, isLoading } = useAdminOrders({
sales_channel_id: [salesChannelId],
offset: 0,
limit: 50,
})
return (
<div>
{isLoading && <span>Loading...</span>}
{orders && orders.length > 0 && (
<ul>
{orders.map((order: Order) => (
<li key={order.id}>{order.display_id}</li>
))}
</ul>
)}
{orders && !orders.length && <span>No Orders</span>}
</div>
)
}
export default SalesChannelOrders
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(`<BACKEND_URL>/admin/orders?sales_channel_id[0]=${salesChannelId}`, {
credentials: "include",
})
.then((response) => response.json())
.then(({ orders, limit, offset, count }) => {
console.log(orders.length)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X GET '<BACKEND_URL>/admin/orders?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
The request returns an array of orders that are associated with the specified sales channel.
@@ -0,0 +1,124 @@
---
description: "Sales channels are different methods a business offers its products for purchase for the customers. Learn about the available features and guides."
---
import DocCardList from '@theme/DocCardList';
import DocCard from '@theme/DocCard';
import Icons from '@theme/Icon';
# Sales Channels
Sales channels are different methods a business offers its products for purchase for the customers. This overview introduces the available features related to sales channels.
:::note
Not a developer? Check out the [Sales Channels user guide](../../user-guide/sales-channels/index.md).
:::
## Features
### Sales Channel Management
Admins can manage sales channels, creating an unlimited number of them. They specify the products’ availability for each sales channel.
<DocCardList colSize={4} items={[
{
type: 'link',
href: '/modules/sales-channels/admin/manage',
label: 'Admin: Manage Sales Channels',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to manage sales channels using the Admin APIs.'
}
},
{
type: 'link',
href: '/user-guide/sales-channels/manage',
label: 'User Guide: Manage Sales Channels',
customProps: {
icon: Icons['users-solid'],
description: 'Learn how to manage sales channels using Medusa Admin.'
}
},
{
type: 'link',
href: '/user-guide/sales-channels/products',
label: 'User Guide: Manage Products',
customProps: {
icon: Icons['users-solid'],
description: 'Learn how to manage products in a sales channel using Medusa Admin.'
}
},
]} />
### Sales Channels for Each Platform
Developers can associate a platform with a sales channel. For example, associating a storefront with a web sales channel. Only products available in that sales channel will be shown, and all orders placed on that sales channel will be associated with it.
Admins can filter orders by a sales channel. This would allow them to handle orders coming from each sales channel differently.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/modules/sales-channels/storefront/use-sales-channels',
label: 'Storefront: Use Sales Channels',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to use sales channels in a storefront.'
}
},
{
type: 'link',
href: '/modules/sales-channels/admin/manage#list-orders-by-sales-channels',
label: 'Admin: Orders by Sales Channels',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to filter orders by a sales channel.'
}
},
]} />
---
## Understand the Architecture
Learn how sales channel related entities and concepts are built, their relation to other modules, and more.
<DocCard item={{
type: 'link',
href: '/modules/sales-channels',
label: 'Architecture: Sales Channel',
customProps: {
icon: Icons['circle-stack-solid'],
description: 'Learn about the Sales Channels architecture.'
}
}}
/>
---
## Related Modules
Discover Sales Channel’s relation to other modules in Medusa.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/modules/products/overview',
label: 'Product',
customProps: {
icon: Icons['tag-solid'],
description: 'Products availability can be changed for each sales channel.'
}
},
{
type: 'link',
href: '/modules/orders/overview',
label: 'Orders',
customProps: {
icon: Icons['shopping-cart-solid'],
description: 'Orders can be associated and organized by a sales channel.'
}
},
]} />
@@ -0,0 +1,67 @@
---
description: 'Learn what Sales Channels are and how they can be used in Medusa. Sales Channels allow merchants to separate between the different channels products are sold in.'
---
# Sales Channels
In this document, you’ll learn about Sales Channels and how they can be used in Medusa.
## Introduction
Sales Channels allow you to separate between the different channels you sell products in. For example, you can have a sales channel for your website and another for your mobile apps.
Sales Channels are associated with stores, products, carts, and orders: A store has a default sales channel; you can define which products are available in a sales channel; you can specify the sales channel of a cart; you can filter orders by sales channel.
### Example Use Cases
The sales channel feature can be used in a variety of use cases including:
- Implement a B2B Ecommerce Store.
- Specifying different products for each channel you sell in.
- Support Omnichannel in your ecommerce store.
---
## SalesChannel Entity Overview
A sales channel is stored in the database as a [SalesChannel](../../references/entities/classes/SalesChannel.md) entity. Some of its important attributes are:
- `name`: The name of the sales channel.
- `is_disabled`: A boolean value indicating of the Sales Channel is disabled or not.
---
## Relations to Other Entities
### Store
A store has a default sales channel. When you first run your Medusa backend or seed your database, a default sales channel is created, if it doesn’t exist, and associated with the store.
The relation is implemented in the [Store](../../references/entities/classes/Store.md) entity. You can access the default sales channel of a store by expanding the `default_sales_channel` relation and using `store.default_sales_channel`. You can also access the ID of the default sales channel using `store.default_sales_channel_id`.
### Product
Products can be available in more than one sales channel. You can then filter products by a sales channel using the Storefront and Admin APIs.
The relation is implemented in the [Product](../../references/entities/classes/Product.md) entity. You can access the sales channels a product is available in by expanding the `sales_channels` relation and using `product.sales_channels`.
### Cart
When you create a cart, you can optionally specify the sales channel it belongs to. If you don’t set the sales channel, the store’s default sales channel will be associated with it.
A cart can belong to only one sales channel. Only products that belong to the same sales channel as the cart can be added to it.
The relation is implemented in the [Cart](../../references/entities/classes/Cart.md) entity. You can access the sales channel a cart is associated with by expanding the `sales_channel` relation and using `cart.sales_channel`. You can also access the ID of the sales channel using `cart.sales_channel_id`.
### Order
Orders can optionally be associated with a sales channel. You can filter orders by a sales channel using the Storefront and Admin APIs.
The relation is implemented in the [Order](../../references/entities/classes/Order.md) entity. You can access the sales channel an order is associated with by expanding the `sales_channel` relation and using `order.sales_channel`. You can also access the ID of the sales channel using `order.sales_channel_id`.
---
## See Also
- [Manage sales channels using the admin APIs](./admin/manage.mdx)
- [Use sales channels in the storefront](./storefront/use-sales-channels.mdx)
@@ -0,0 +1,256 @@
---
description: 'Learn how to implement sales channel functionalities in the storefront using REST APIs. This includes filtering products by Sales Channel and associating a cart with a sales channel.'
addHowToData: true
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# How to Use Sales Channels in Storefronts
In this document, you’ll learn how to use sales channels in your storefront.
## Overview
In your storefront, you can filter products by sales channels. You can also associate carts with a sales channel.
This guide explains how to perform these operations using the Storefront APIs.
### Alternative Approach: Publishable API keys
This guide covers how to pass the sales channel ID into different requests to retrieve or process data associated with the sales channel.
An alternative approach is to use Publishable API keys. You can learn how to use them in the following documents:
- [Using publishable API keys in requests](../../../development/publishable-api-keys/index.mdx)
- Managing publishable API keys using [admin APIs](../../../development/publishable-api-keys/admin/manage-publishable-api-keys.mdx) or using [Medusa Admin](../../../user-guide/settings/publishable-api-keys.mdx)
---
## Prerequisites
### Medusa Components
It's assumed that you already have a Medusa backend installed and set up. If not, you can follow our [quickstart guide](../../../development/backend/install.mdx) to get started.
It is also assumed you already have a storefront set up. It can be a custom storefront or one of Medusa’s storefronts. If you don’t have a storefront set up, you can install the [Next.js Starter Template](../../../starters/nextjs-medusa-starter.mdx).
### JS Client
This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client installed](../../../js-client/overview.md) and have [created an instance of the client](../../../js-client/overview.md#configuration).
### Medusa React
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.mdx) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.mdx#usage).
For requests that use the cart, it's also assumed you already have [used CartProvider higher in your component tree](../../../medusa-react/overview.mdx#cartprovider).
---
## Filter Products by Sales Channel
To filter products by a specific sales channel, pass the `sales_channel_id` query parameter to the List Products endpoint:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.products.list({
sales_channel_id: [
salesChannelId,
],
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Product } from "@medusajs/medusa"
import { useProducts } from "medusa-react"
const Products = () => {
const { products, isLoading } = useProducts({
sales_channel_id: [
salesChannelId,
],
})
return (
<div>
{isLoading && <span>Loading...</span>}
{products && products.length > 0 && (
<ul>
{products.map((product: Product) => (
<li key={product.id}>{product.title}</li>
))}
</ul>
)}
{products && !products.length && <span>No Products</span>}
</div>
)
}
export default Products
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(`<BACKEND_URL>/store/products?sales_channel_id[0]=${salesChannelId}`)
.then((response) => response.json())
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})
```
</TabItem>
</Tabs>
The `sales_channel_id` query parameter is an array of sales channel IDs. You can pass more than one sales channel.
The request returns an array of products. These are the products that are available in the sales channel.
---
## Associate a Cart with a Sales Channel
### When Creating a Cart
To associate a sales channel with a cart while creating it, you can pass the `sales_channel_id` request body parameter with the ID of the sales channel:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.carts.create({
sales_channel_id: salesChannelId,
})
.then(({ cart }) => {
console.log(cart.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
const { cart, createCart } = useCart()
const handleCreateCart = () => {
createCart.mutate(
{
sales_channel_id: salesChannelId,
},
{
onSuccess: ({ cart }) => {
localStorage.setItem("cart_id", cart.id)
},
}
)
}
// ...
}
export default Cart
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/carts`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
sales_channel_id: salesChannelId,
}),
})
.then((response) => response.json())
.then(({ cart }) => {
console.log(cart.id)
})
```
</TabItem>
</Tabs>
The request returns the created cart.
### Updating an Existing Cart
You can update the sales channel of an existing cart by passing the `sales_channel_id` request body parameter with the ID of the sales channel:
<Tabs groupId="request-type" isCodeTabs={true}>
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.carts.update(cartId, {
sales_channel_id: salesChannelId,
})
.then(({ cart }) => {
console.log(cart.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const changeSalesChannel = (salesChannelId: string) => {
updateCart.mutate({
sales_channel_id: salesChannelId,
})
}
// ...
}
export default Cart
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/carts/${cartId}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
sales_channel_id: salesChannelId,
}),
})
.then((response) => response.json())
.then(({ cart }) => console.log(cart.id))
```
</TabItem>
</Tabs>
The request returns the updated cart.