-
- {title}
-
-
- {isValueString ? (
-
- {value ?? "-"}
-
- ) : (
-
{value}
- )}
-
- {actions &&
{actions}
}
+
+
+ {firstCol}
+
+
+ {secondCol}
+
)
}
```
-The `SectionRow` component shows a title and a value in the same row.
+The `TwoColumnLayout` accepts two props:
-It accepts the following props:
-
-- title: (\`string\`) The title to show on the left side.
-- value: (\`React.ReactNode\` \\| \`string\` \\| \`null\`) The value to show on the right side.
-- actions: (\`React.ReactNode\`) The actions to show at the end of the row.
+- `firstCol` indicating the content of the first column.
+- `secondCol` indicating the content of the second column.
***
## Example
-Use the `SectionRow` component in any widget or UI route.
+Use the `TwoColumnLayout` component in your UI routes that have a single column. For example:
-For example, create the widget `src/admin/widgets/product-widget.tsx` with the following content:
+```tsx title="src/admin/routes/custom/page.tsx" highlights={[["9"]]}
+import { defineRouteConfig } from "@medusajs/admin-sdk"
+import { ChatBubbleLeftRight } from "@medusajs/icons"
+import { Container } from "../../components/container"
+import { Header } from "../../components/header"
+import { TwoColumnLayout } from "../../layouts/two-column"
-```tsx title="src/admin/widgets/product-widget.tsx"
-import { defineWidgetConfig } from "@medusajs/admin-sdk"
-import { Container } from "../components/container"
-import { Header } from "../components/header"
-import { SectionRow } from "../components/section-row"
-
-const ProductWidget = () => {
+const CustomPage = () => {
return (
-
-
-
-
+
+
+
+ }
+ secondCol={
+
+
+
+ }
+ />
)
}
-export const config = defineWidgetConfig({
- zone: "product.details.before",
+export const config = defineRouteConfig({
+ label: "Custom",
+ icon: ChatBubbleLeftRight,
})
-export default ProductWidget
+export default CustomPage
```
-This widget also uses the [Container](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/admin-components/components/container/index.html.md) and [Header](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/admin-components/components/header/index.html.md) custom component.
+This UI route also uses [Container](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/admin-components/components/container/index.html.md) and [Header]() custom components.
# Service Factory Reference
@@ -30355,147 +30527,160 @@ Some examples of method names:
The reference uses only the operation name to refer to the method.
-# Filter Records - Service Factory Reference
+# list Method - Service Factory Reference
-Many of the service factory's generated methods allow passing filters to perform an operation, such as to update or delete records matching the filters.
+This method retrieves a list of records.
-This guide provides examples of using filters.
+## Retrieve List of Records
-The `list` method is used in the example snippets of this reference, but you can use the same filtering mechanism with any method that accepts filters.
+```ts
+const posts = await postModuleService.listPosts()
+```
+
+If no parameters are passed, the method returns an array of the first `15` records.
***
-## Match Exact Value
+## Filter Records
```ts
const posts = await postModuleService.listPosts({
- name: "My Post 2",
+ id: ["123", "321"],
})
```
-If you pass a property with its value, only records whose properties exactly match the value are selected.
+### Parameters
-In the example above, only posts having the name `My Post 2` are retrieved.
+To retrieve records matching a set of filters, pass an object of the filters as a first parameter.
+
+Learn more about accepted filters in [this documentation](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/service-factory-reference/tips/filtering/index.html.md).
+
+### Returns
+
+The method returns an array of the first `15` records matching the filters.
***
-## Match Multiple Values
+## Retrieve Relations
+
+This applies to relations between data models of the same module. To retrieve linked records of different modules, use [Query](https://docs.medusajs.com/docs/learn/fundamentals/module-links/query/index.html.md).
```ts
-const posts = await postModuleService.listPosts({
- views: [
- 50,
- 100,
- ],
+const posts = await postModuleService.listPosts({}, {
+ relations: ["author"],
})
```
-To find records with a property matching multiple values, pass an array of those values as the property's value in the filter.
+### Parameters
-In the example above, only posts having either `50` or `100` views are retrieved.
+To retrieve records with their relations, pass as a second parameter an object having a `relations` property. `relations`'s value is an array of relation names.
+
+### Returns
+
+The method returns an array of the first `15` records matching the filters.
***
-## Don't Match Values
+## Select Properties
```ts
-const posts = await postModuleService.listPosts({
- name: {
- $nin: [
- "My Post",
- ],
+const posts = await postModuleService.listPosts({}, {
+ select: ["id", "name"],
+})
+```
+
+### Parameters
+
+By default, retrieved records have all their properties. To select specific properties to retrieve, pass in the second object parameter a `select` property.
+
+`select`'s value is an array of property names to retrieve.
+
+### Returns
+
+The method returns an array of the first `15` records matching the filters.
+
+***
+
+## Paginate Relations
+
+```ts
+const posts = await postModuleService.listPosts({}, {
+ take: 20,
+ skip: 10,
+})
+```
+
+### Parameters
+
+To paginate the returned records, the second object parameter accepts the following properties:
+
+- `take`: a number indicating how many records to retrieve. By default, it's `15`.
+- `skip`: a number indicating how many records to skip before the retrieved records. By default, it's `0`.
+
+### Returns
+
+The method returns an array of records. The number of records is less than or equal to `take`'s value.
+
+***
+
+## Sort Records
+
+```ts
+const posts = await postModuleService.listPosts({}, {
+ order: {
+ name: "ASC",
},
})
```
-To find records with a property that doesn't match one or more values, pass an object with a `$nin` property. Its value is an array of multiple values that a record's property shouldn't match.
+### Parameters
-In the example above, only posts that don't have the name `My Post` are retrieved.
+To sort records by one or more properties, pass to the second object parameter the `order` property. Its value is an object whose keys are the property names, and values can either be:
-***
+- `ASC` to sort by this property in the ascending order.
+- `DESC` to sort by this property in the descending order.
-## Match Text Like Value
+### Returns
-This filter only applies to text-like properties, including `id` and `enum` properties.
+The method returns an array of the first `15` records matching the filters.
+
+
+# create Method - Service Factory Reference
+
+This method creates one or more records of the data model.
+
+## Create One Record
```ts
-const posts = await postModuleService.listPosts({
- name: {
- $like: "My%",
+const post = await postModuleService.createPosts({
+ name: "My Post",
+ published_at: new Date(),
+ metadata: {
+ external_id: "1234",
},
})
```
-To perform a `like` filter on a record's property, set the property's value to an object with a `$like` property. Its value is the string to use when applying the `like` filter.
-
-The example above matches all posts whose name starts with `My`.
+If an object is passed of the method, an object of the created record is also returned.
***
-## Apply Range Filters
-
-This filter only applies to the `number` and `dateTime` properties.
+## Create Multiple Records
```ts
-const posts = await postModuleService.listPosts({
- published_at: {
- $lt: new Date(),
+const posts = await postModuleService.createPosts([
+ {
+ name: "My Post",
+ published_at: new Date(),
},
-})
-```
-
-To filter a record's property to be within a range, set the property's value to an object with any of the following properties:
-
-1. `$lt`: The property's value must be less than the supplied value.
-2. `$lte`: The property's value must be less than or equal to the supplied value.
-3. `$gt`: The property's value must be greater than the supplied value.
-4. `$gte`: The property's value must be greater than or equal the supplied value.
-
-In the example above, only posts whose `published_at` property is before the current date and time are retrieved.
-
-### Example: Retrieve Posts Published Today
-
-```ts
-const startToday = new Date()
-startToday.setHours(0, 0, 0, 0)
-
-const endToday = new Date()
-endToday.setHours(23, 59, 59, 59)
-
-const posts = await postModuleService.listPosts({
- published_at: {
- $gte: startToday,
- $lte: endToday,
+ {
+ name: "My Other Post",
+ published_at: new Date(),
},
-})
+])
```
-The `dateTime` property also stores the time. So, when matching for an exact day, you must set a range filter to be between the beginning and end of the day.
-
-In this example, you retrieve the current date twice: once to set its time to `00:00:00`, and another to set its time `23:59:59`. Then, you retrieve posts whose `published_at` property is between `00:00:00` and `23:59:59` of today.
-
-***
-
-## Apply Or Condition
-
-```ts
-const posts = await postModuleService.listPosts({
- $or: [
- {
- name: "My Post",
- },
- {
- published_at: {
- $lt: new Date(),
- },
- },
- ],
-})
-```
-
-To use an `or` condition, pass to the filter object the `$or` property, whose value is an array of filters.
-
-In the example above, posts whose name is `My Post` or their `published_at` date is less than the current date and time are retrieved.
+If an array is passed of the method, an array of the created records is also returned.
# delete Method - Service Factory Reference
@@ -30538,44 +30723,6 @@ To delete records matching a set of filters, pass an object of filters as a para
Learn more about accepted filters in [this documentation](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/service-factory-reference/tips/filtering/index.html.md).
-# create Method - Service Factory Reference
-
-This method creates one or more records of the data model.
-
-## Create One Record
-
-```ts
-const post = await postModuleService.createPosts({
- name: "My Post",
- published_at: new Date(),
- metadata: {
- external_id: "1234",
- },
-})
-```
-
-If an object is passed of the method, an object of the created record is also returned.
-
-***
-
-## Create Multiple Records
-
-```ts
-const posts = await postModuleService.createPosts([
- {
- name: "My Post",
- published_at: new Date(),
- },
- {
- name: "My Other Post",
- published_at: new Date(),
- },
-])
-```
-
-If an array is passed of the method, an array of the created records is also returned.
-
-
# listAndCount Method - Service Factory Reference
This method retrieves a list of records with the total count.
@@ -30799,92 +30946,62 @@ restoredPosts = {
```
-# softDelete Method - Service Factory Reference
+# retrieve Method - Service Factory Reference
-This method soft deletes one or more records of the data model.
+This method retrieves one record of the data model by its ID.
-## Soft Delete One Record
+## Retrieve a Record
```ts
-const deletedPosts = await postModuleService.softDeletePosts(
- "123"
-)
+const post = await postModuleService.retrievePost("123")
```
### Parameters
-To soft delete a record, pass its ID as a parameter of the method.
+Pass the ID of the record to retrieve.
### Returns
-The method returns an object, whose keys are of the format `{camel_case_data_model_name}_id`, and their values are arrays of soft-deleted records' IDs.
-
-For example, the returned object of the above example is:
-
-```ts
-deletedPosts = {
- post_id: ["123"],
-}
-```
+The method returns the record as an object.
***
-## Soft Delete Multiple Records
+## Retrieve a Record's Relations
+
+This applies to relations between data models of the same module. To retrieve linked records of different modules, use [Query](https://docs.medusajs.com/docs/learn/fundamentals/module-links/query/index.html.md).
```ts
-const deletedPosts = await postModuleService.softDeletePosts([
- "123",
- "321",
-])
-```
-
-### Parameters
-
-To soft delete multiple records, pass an array of IDs as a parameter of the method.
-
-### Returns
-
-The method returns an object, whose keys are of the format `{camel_case_data_model_name}_id`, and their values are arrays of soft-deleted records' IDs.
-
-For example, the returned object of the above example is:
-
-```ts
-deletedPosts = {
- post_id: [
- "123",
- "321",
- ],
-}
-```
-
-***
-
-## Soft Delete Records Matching Filters
-
-```ts
-const deletedPosts = await postModuleService.softDeletePosts({
- name: "My Post",
+const post = await postModuleService.retrievePost("123", {
+ relations: ["author"],
})
```
### Parameters
-To soft delete records matching a set of filters, pass an object of filters as a parameter.
-
-Learn more about accepted filters in [this documentation](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/service-factory-reference/tips/filtering/index.html.md).
+To retrieve the data model with relations, pass as a second parameter of the method an object with the property `relations`. `relations`'s value is an array of relation names.
### Returns
-The method returns an object, whose keys are of the format `{camel_case_data_model_name}_id`, and their values are arrays of soft-deleted records' IDs.
+The method returns the record as an object.
-For example, the returned object of the above example is:
+***
+
+## Select Properties to Retrieve
```ts
-deletedPosts = {
- post_id: ["123"],
-}
+const post = await postModuleService.retrievePost("123", {
+ select: ["id", "name"],
+})
```
+### Parameters
+
+By default, all of the record's properties are retrieved. To select specific ones, pass in the second object parameter a `select` property. Its value is an array of property names.
+
+### Returns
+
+The method returns the record as an object.
+
# update Method - Service Factory Reference
@@ -31009,179 +31126,234 @@ Learn more about accepted filters in [this documentation](https://docs.medusajs.
The method returns an array of objects of updated records.
-# retrieve Method - Service Factory Reference
+# softDelete Method - Service Factory Reference
-This method retrieves one record of the data model by its ID.
+This method soft deletes one or more records of the data model.
-## Retrieve a Record
+## Soft Delete One Record
```ts
-const post = await postModuleService.retrievePost("123")
+const deletedPosts = await postModuleService.softDeletePosts(
+ "123"
+)
```
### Parameters
-Pass the ID of the record to retrieve.
+To soft delete a record, pass its ID as a parameter of the method.
### Returns
-The method returns the record as an object.
+The method returns an object, whose keys are of the format `{camel_case_data_model_name}_id`, and their values are arrays of soft-deleted records' IDs.
+
+For example, the returned object of the above example is:
+
+```ts
+deletedPosts = {
+ post_id: ["123"],
+}
+```
***
-## Retrieve a Record's Relations
-
-This applies to relations between data models of the same module. To retrieve linked records of different modules, use [Query](https://docs.medusajs.com/docs/learn/fundamentals/module-links/query/index.html.md).
+## Soft Delete Multiple Records
```ts
-const post = await postModuleService.retrievePost("123", {
- relations: ["author"],
+const deletedPosts = await postModuleService.softDeletePosts([
+ "123",
+ "321",
+])
+```
+
+### Parameters
+
+To soft delete multiple records, pass an array of IDs as a parameter of the method.
+
+### Returns
+
+The method returns an object, whose keys are of the format `{camel_case_data_model_name}_id`, and their values are arrays of soft-deleted records' IDs.
+
+For example, the returned object of the above example is:
+
+```ts
+deletedPosts = {
+ post_id: [
+ "123",
+ "321",
+ ],
+}
+```
+
+***
+
+## Soft Delete Records Matching Filters
+
+```ts
+const deletedPosts = await postModuleService.softDeletePosts({
+ name: "My Post",
})
```
### Parameters
-To retrieve the data model with relations, pass as a second parameter of the method an object with the property `relations`. `relations`'s value is an array of relation names.
-
-### Returns
-
-The method returns the record as an object.
-
-***
-
-## Select Properties to Retrieve
-
-```ts
-const post = await postModuleService.retrievePost("123", {
- select: ["id", "name"],
-})
-```
-
-### Parameters
-
-By default, all of the record's properties are retrieved. To select specific ones, pass in the second object parameter a `select` property. Its value is an array of property names.
-
-### Returns
-
-The method returns the record as an object.
-
-
-# list Method - Service Factory Reference
-
-This method retrieves a list of records.
-
-## Retrieve List of Records
-
-```ts
-const posts = await postModuleService.listPosts()
-```
-
-If no parameters are passed, the method returns an array of the first `15` records.
-
-***
-
-## Filter Records
-
-```ts
-const posts = await postModuleService.listPosts({
- id: ["123", "321"],
-})
-```
-
-### Parameters
-
-To retrieve records matching a set of filters, pass an object of the filters as a first parameter.
+To soft delete records matching a set of filters, pass an object of filters as a parameter.
Learn more about accepted filters in [this documentation](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/service-factory-reference/tips/filtering/index.html.md).
### Returns
-The method returns an array of the first `15` records matching the filters.
+The method returns an object, whose keys are of the format `{camel_case_data_model_name}_id`, and their values are arrays of soft-deleted records' IDs.
+
+For example, the returned object of the above example is:
+
+```ts
+deletedPosts = {
+ post_id: ["123"],
+}
+```
+
+
+# Filter Records - Service Factory Reference
+
+Many of the service factory's generated methods allow passing filters to perform an operation, such as to update or delete records matching the filters.
+
+This guide provides examples of using filters.
+
+The `list` method is used in the example snippets of this reference, but you can use the same filtering mechanism with any method that accepts filters.
***
-## Retrieve Relations
-
-This applies to relations between data models of the same module. To retrieve linked records of different modules, use [Query](https://docs.medusajs.com/docs/learn/fundamentals/module-links/query/index.html.md).
+## Match Exact Value
```ts
-const posts = await postModuleService.listPosts({}, {
- relations: ["author"],
+const posts = await postModuleService.listPosts({
+ name: "My Post 2",
})
```
-### Parameters
+If you pass a property with its value, only records whose properties exactly match the value are selected.
-To retrieve records with their relations, pass as a second parameter an object having a `relations` property. `relations`'s value is an array of relation names.
-
-### Returns
-
-The method returns an array of the first `15` records matching the filters.
+In the example above, only posts having the name `My Post 2` are retrieved.
***
-## Select Properties
+## Match Multiple Values
```ts
-const posts = await postModuleService.listPosts({}, {
- select: ["id", "name"],
+const posts = await postModuleService.listPosts({
+ views: [
+ 50,
+ 100,
+ ],
})
```
-### Parameters
+To find records with a property matching multiple values, pass an array of those values as the property's value in the filter.
-By default, retrieved records have all their properties. To select specific properties to retrieve, pass in the second object parameter a `select` property.
-
-`select`'s value is an array of property names to retrieve.
-
-### Returns
-
-The method returns an array of the first `15` records matching the filters.
+In the example above, only posts having either `50` or `100` views are retrieved.
***
-## Paginate Relations
+## Don't Match Values
```ts
-const posts = await postModuleService.listPosts({}, {
- take: 20,
- skip: 10,
-})
-```
-
-### Parameters
-
-To paginate the returned records, the second object parameter accepts the following properties:
-
-- `take`: a number indicating how many records to retrieve. By default, it's `15`.
-- `skip`: a number indicating how many records to skip before the retrieved records. By default, it's `0`.
-
-### Returns
-
-The method returns an array of records. The number of records is less than or equal to `take`'s value.
-
-***
-
-## Sort Records
-
-```ts
-const posts = await postModuleService.listPosts({}, {
- order: {
- name: "ASC",
+const posts = await postModuleService.listPosts({
+ name: {
+ $nin: [
+ "My Post",
+ ],
},
})
```
-### Parameters
+To find records with a property that doesn't match one or more values, pass an object with a `$nin` property. Its value is an array of multiple values that a record's property shouldn't match.
-To sort records by one or more properties, pass to the second object parameter the `order` property. Its value is an object whose keys are the property names, and values can either be:
+In the example above, only posts that don't have the name `My Post` are retrieved.
-- `ASC` to sort by this property in the ascending order.
-- `DESC` to sort by this property in the descending order.
+***
-### Returns
+## Match Text Like Value
-The method returns an array of the first `15` records matching the filters.
+This filter only applies to text-like properties, including `id` and `enum` properties.
+
+```ts
+const posts = await postModuleService.listPosts({
+ name: {
+ $like: "My%",
+ },
+})
+```
+
+To perform a `like` filter on a record's property, set the property's value to an object with a `$like` property. Its value is the string to use when applying the `like` filter.
+
+The example above matches all posts whose name starts with `My`.
+
+***
+
+## Apply Range Filters
+
+This filter only applies to the `number` and `dateTime` properties.
+
+```ts
+const posts = await postModuleService.listPosts({
+ published_at: {
+ $lt: new Date(),
+ },
+})
+```
+
+To filter a record's property to be within a range, set the property's value to an object with any of the following properties:
+
+1. `$lt`: The property's value must be less than the supplied value.
+2. `$lte`: The property's value must be less than or equal to the supplied value.
+3. `$gt`: The property's value must be greater than the supplied value.
+4. `$gte`: The property's value must be greater than or equal the supplied value.
+
+In the example above, only posts whose `published_at` property is before the current date and time are retrieved.
+
+### Example: Retrieve Posts Published Today
+
+```ts
+const startToday = new Date()
+startToday.setHours(0, 0, 0, 0)
+
+const endToday = new Date()
+endToday.setHours(23, 59, 59, 59)
+
+const posts = await postModuleService.listPosts({
+ published_at: {
+ $gte: startToday,
+ $lte: endToday,
+ },
+})
+```
+
+The `dateTime` property also stores the time. So, when matching for an exact day, you must set a range filter to be between the beginning and end of the day.
+
+In this example, you retrieve the current date twice: once to set its time to `00:00:00`, and another to set its time `23:59:59`. Then, you retrieve posts whose `published_at` property is between `00:00:00` and `23:59:59` of today.
+
+***
+
+## Apply Or Condition
+
+```ts
+const posts = await postModuleService.listPosts({
+ $or: [
+ {
+ name: "My Post",
+ },
+ {
+ published_at: {
+ $lt: new Date(),
+ },
+ },
+ ],
+})
+```
+
+To use an `or` condition, pass to the filter object the `$or` property, whose value is an array of filters.
+
+In the example above, posts whose name is `My Post` or their `published_at` date is less than the current date and time are retrieved.
@@ -31624,6 +31796,125 @@ How to install and setup Medusa UI.
+# Medusa Admin Extension
+
+How to install and use Medusa UI for building Admin extensions.
+
+## Installation
+
+***
+
+The `@medusajs/ui` package is a already installed as a dependency of the `@medusajs/admin` package. Due to this you can simply import the package and use it in your local Admin extensions.
+
+If you are building a Admin extension as part of a Medusa plugin, you can install the package as a dependency of your plugin.
+
+```bash
+npm install @medusajs/ui
+```
+
+## Configuration
+
+***
+
+The configuration of the UI package is handled by the `@medusajs/admin` package. Therefore, you do not need to any additional configuration to use the UI package in your Admin extensions.
+
+
+# Standalone Project
+
+How to install and use Medusa UI in a standalone project.
+
+## Installation
+
+***
+
+Medusa UI is a React UI library and while it's intended for usage within Medusa projects, it can also be used in any React project.
+
+### Install Medusa UI
+
+Install the React UI library with the following command:
+
+```bash
+npm install @medusajs/ui
+```
+
+### Configuring Tailwind CSS
+
+The components are styled using Tailwind CSS, and in order to use them, you will need to install Tailwind CSS in your project as well.
+For more information on how to install Tailwind CSS, please refer to the [Tailwind CSS documentation](https://tailwindcss.com/docs/installation).
+
+All of the classes used for Medusa UI are shipped as a Tailwind CSS customization.
+You can install it with the following command:
+
+```bash
+npm install @medusajs/ui-preset
+```
+
+After you have installed Tailwind CSS and the Medusa UI preset, you need to add the following to your `tailwind.config.js`file:
+
+```tsx
+module.exports = {
+ presets: [require("@medusajs/ui-preset")],
+ // ...
+}
+```
+
+In order for the styles to be applied correctly to the components, you will also need to ensure that
+`@medusajs/ui` is included in the content field of your `tailwind.config.js` file:
+
+```tsx
+module.exports = {
+ content: [
+ // ...
+ "./node_modules/@medusajs/ui/dist/**/*.{js,jsx,ts,tsx}",
+ ],
+ // ...
+}
+```
+
+If you are working within a monorepo, you may need to add the path to the `@medusajs/ui` package in your `tailwind.config.js` like so:
+
+```tsx
+const path = require("path")
+
+const uiPath = path.resolve(
+ require.resolve("@medusajs/ui"),
+ "../..",
+ "\*_/_.{js,jsx,ts,tsx}"
+)
+
+module.exports = {
+ content: [
+ // ...
+ uiPath,
+ ],
+ // ...
+}
+
+```
+
+## Start building
+
+***
+
+You are now ready to start building your application with Medusa UI. You can import the components like so:
+
+```tsx
+import { Button, Drawer } from "@medusajs/ui"
+```
+
+## Updating UI Packages
+
+***
+
+Medusa's design-system packages, including `@medusajs/ui`, `@medusajs/ui-preset`, and `@medusajs/ui-icons`, are versioned independently. However, they're still part of the latest Medusa release. So, you can browse the [release notes](https://github.com/medusajs/medusa/releases) to see if there are any breaking changes to these packages.
+
+To update these packages, update their version in your `package.json` file and re-install dependencies. For example:
+
+```bash
+npm install @medusajs/ui
+```
+
+
# Alert
A component for displaying important messages.
@@ -37838,125 +38129,6 @@ If you're using the `Tooltip` component in a project other than the Medusa Admin
- disableHoverableContent: (boolean) When \`true\`, trying to hover the content will result in the tooltip closing as the pointer leaves the trigger.
-# Medusa Admin Extension
-
-How to install and use Medusa UI for building Admin extensions.
-
-## Installation
-
-***
-
-The `@medusajs/ui` package is a already installed as a dependency of the `@medusajs/admin` package. Due to this you can simply import the package and use it in your local Admin extensions.
-
-If you are building a Admin extension as part of a Medusa plugin, you can install the package as a dependency of your plugin.
-
-```bash
-npm install @medusajs/ui
-```
-
-## Configuration
-
-***
-
-The configuration of the UI package is handled by the `@medusajs/admin` package. Therefore, you do not need to any additional configuration to use the UI package in your Admin extensions.
-
-
-# Standalone Project
-
-How to install and use Medusa UI in a standalone project.
-
-## Installation
-
-***
-
-Medusa UI is a React UI library and while it's intended for usage within Medusa projects, it can also be used in any React project.
-
-### Install Medusa UI
-
-Install the React UI library with the following command:
-
-```bash
-npm install @medusajs/ui
-```
-
-### Configuring Tailwind CSS
-
-The components are styled using Tailwind CSS, and in order to use them, you will need to install Tailwind CSS in your project as well.
-For more information on how to install Tailwind CSS, please refer to the [Tailwind CSS documentation](https://tailwindcss.com/docs/installation).
-
-All of the classes used for Medusa UI are shipped as a Tailwind CSS customization.
-You can install it with the following command:
-
-```bash
-npm install @medusajs/ui-preset
-```
-
-After you have installed Tailwind CSS and the Medusa UI preset, you need to add the following to your `tailwind.config.js`file:
-
-```tsx
-module.exports = {
- presets: [require("@medusajs/ui-preset")],
- // ...
-}
-```
-
-In order for the styles to be applied correctly to the components, you will also need to ensure that
-`@medusajs/ui` is included in the content field of your `tailwind.config.js` file:
-
-```tsx
-module.exports = {
- content: [
- // ...
- "./node_modules/@medusajs/ui/dist/**/*.{js,jsx,ts,tsx}",
- ],
- // ...
-}
-```
-
-If you are working within a monorepo, you may need to add the path to the `@medusajs/ui` package in your `tailwind.config.js` like so:
-
-```tsx
-const path = require("path")
-
-const uiPath = path.resolve(
- require.resolve("@medusajs/ui"),
- "../..",
- "\*_/_.{js,jsx,ts,tsx}"
-)
-
-module.exports = {
- content: [
- // ...
- uiPath,
- ],
- // ...
-}
-
-```
-
-## Start building
-
-***
-
-You are now ready to start building your application with Medusa UI. You can import the components like so:
-
-```tsx
-import { Button, Drawer } from "@medusajs/ui"
-```
-
-## Updating UI Packages
-
-***
-
-Medusa's design-system packages, including `@medusajs/ui`, `@medusajs/ui-preset`, and `@medusajs/ui-icons`, are versioned independently. However, they're still part of the latest Medusa release. So, you can browse the [release notes](https://github.com/medusajs/medusa/releases) to see if there are any breaking changes to these packages.
-
-To update these packages, update their version in your `package.json` file and re-install dependencies. For example:
-
-```bash
-npm install @medusajs/ui
-```
-
-
# clx
Utility function for working with classNames.
diff --git a/www/apps/book/sidebar.mjs b/www/apps/book/sidebar.mjs
index 4e35b35ce4..a9ee2317f4 100644
--- a/www/apps/book/sidebar.mjs
+++ b/www/apps/book/sidebar.mjs
@@ -466,6 +466,11 @@ export const sidebar = sidebarAttachHrefCommonOptions([
path: "/learn/fundamentals/admin/environment-variables",
title: "Environment Variables",
},
+ {
+ type: "link",
+ path: "/learn/fundamentals/admin/routing",
+ title: "Routing Customizations",
+ },
{
type: "link",
path: "/learn/fundamentals/admin/constraints",
diff --git a/www/apps/resources/app/js-sdk/page.mdx b/www/apps/resources/app/js-sdk/page.mdx
index b91c004953..0bdcb7d737 100644
--- a/www/apps/resources/app/js-sdk/page.mdx
+++ b/www/apps/resources/app/js-sdk/page.mdx
@@ -185,6 +185,8 @@ The `Medusa` initializer accepts as a parameter an object with the following pro
- `local` for the Local Storage.
- `session` for the Session Storage.
- `memory` to store it within the SDK for the current application's runtime.
+ - `custom` to define custom storage using the `auth.storage` configuration. If `auth.storage` isn't defined, the SDK throws an error. This option is only available after Medusa v2.5.1.
+ - `nostore` to not store the token.
@@ -196,6 +198,29 @@ The `Medusa` initializer accepts as a parameter an object with the following pro
+ `auth.storage`
+
+
+
+
+ This option is only available after Medusa v2.5.1. It's an object or class that's used when `auth.jwtTokenStorageMethod` is `custom` to store the JWT token. It's useful when using the JS SDK in an environment where Local or Session Storage isn't available. The object or class must have the following methods:
+
+ - `setItem`: A function that accepts a key and value to store the JWT token.
+ - `getItem`: A function that accepts a key to retrieve the JWT token.
+ - `removeItem`: A function that accepts a key to remove the JWT token from storage.
+
+ Learn more in [this section](#use-custom-storage).
+
+
+
+
+ \-
+
+
+
+
+
+
`auth.fetchCredentials`
@@ -484,3 +509,49 @@ revalidateTag("products")
```
Learn more in the [Next.js documentation](https://nextjs.org/docs/app/building-your-application/caching#fetch-optionsnexttags-and-revalidatetag).
+
+### Use Custom Storage
+
+
+
+The `auth.storage` configuration is only available after Medusa v2.5.1.
+
+
+
+If you're using the JS SDK in an environment where Local Storage or Session Storage isn't available, such as in a React Native application, you can define custom logic to store the JWT token.
+
+To do that, set the `auth.jwtTokenStorageMethod` configuration to `custom` and define the `auth.storage` configuration with the custom logic to store the JWT token.
+
+For example, if you're using React Native's `AsyncStorage`:
+
+```ts title="config.ts"
+import AsyncStorage from "@react-native-async-storage/async-storage"
+import Medusa from "@medusajs/js-sdk"
+
+let MEDUSA_BACKEND_URL = "http://localhost:9000"
+
+if (process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL) {
+ MEDUSA_BACKEND_URL = process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL
+}
+
+export const sdk = new Medusa({
+ baseUrl: MEDUSA_BACKEND_URL,
+ debug: process.env.NODE_ENV === "development",
+ publishableKey: process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY,
+ auth: {
+ type: "jwt",
+ jwtTokenStorageMethod: "custom",
+ storge: AsyncStorage,
+ },
+})
+```
+
+In the `auth` configuration, you specify the `type` as `jwt`, the `jwtTokenStorageMethod` as `custom`, and the `storage` as `AsyncStorage`. So, the SDK uses `AsyncStorage` to store the JWT token.
+
+#### Custom Storage Methods
+
+The object or class passed to `auth.storage` configuration must have the following methods:
+
+- `setItem`: A function that accepts a key and value to store the JWT token.
+- `getItem`: A function that accepts a key to retrieve the JWT token.
+- `removeItem`: A function that accepts a key to remove the JWT token from storage.
diff --git a/www/apps/resources/app/plugins/guides/wishlist/page.mdx b/www/apps/resources/app/plugins/guides/wishlist/page.mdx
index 293a6db628..56bd1f2530 100644
--- a/www/apps/resources/app/plugins/guides/wishlist/page.mdx
+++ b/www/apps/resources/app/plugins/guides/wishlist/page.mdx
@@ -1207,7 +1207,7 @@ export const createWishlistItemWorkflow = createWorkflow(
})
validateWishlistExistsStep({
- wishlists
+ wishlists,
})
validateWishlistSalesChannelStep({
@@ -1604,7 +1604,7 @@ export const deleteWishlistItemWorkflow = createWorkflow(
})
validateWishlistExistsStep({
- wishlists
+ wishlists,
})
validateItemInWishlistStep({
diff --git a/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx b/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx
index c275cbae99..f39bd335ea 100644
--- a/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx
+++ b/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx
@@ -1403,7 +1403,7 @@ fetch(`/admin/digital-products`, {
// delegate setting the prices to the
// product's page.
prices: [],
- shipping_profile_id: ""
+ shipping_profile_id: "",
}],
},
}),