Admin Routing Customizations

The Medusa Admin dashboard uses React Router under the hood to manage routing. So, you can have more flexibility in routing-related customizations using some of React Router's utilities, hooks, and components.

In this chapter, you'll learn about routing-related customizations that you can use in your admin customizations using React Router.

Notereact-router-dom is available in your project by default through the Medusa packages. You don't need to install it separately.

To link to a page in your admin customizations, you can use the Link component from react-router-dom. For example:

src/admin/widgets/product-widget.tsx
1import { defineWidgetConfig } from "@medusajs/admin-sdk"2import { Container } from "@medusajs/ui"3import { Link } from "react-router-dom"4
5// The widget6const ProductWidget = () => {7  return (8    <Container className="divide-y p-0">9      <Link to={"/orders"}>View Orders</Link>10    </Container>11  )12}13
14// The widget's configurations15export const config = defineWidgetConfig({16  zone: "product.details.before",17})18
19export default ProductWidget

This adds a widget to a product's details page with a link to the Orders page. The link's path must be without the /app prefix.


Admin Route Loader#

NoteRoute loaders are available starting from Medusa v2.5.1.

In your UI route or any other custom admin route, you may need to retrieve data to use it in your route component. For example, you may want to fetch a list of products to display on a custom page.

To do that, you can export a loader function in the route file, which is a React Router loader. In this function, you can fetch and return data asynchronously. Then, in your route component, you can use the useLoaderData hook from React Router to access the data.

For example, consider the following UI route created at src/admin/routes/custom/page.tsx:

src/admin/routes/custom/page.tsx
1import { Container, Heading } from "@medusajs/ui"2import {3  useLoaderData,4} from "react-router-dom"5
6export async function loader() {7  // TODO fetch products8
9  return {10    products: [],11  }12}13
14const CustomPage = () => {15  const { products } = useLoaderData() as Awaited<ReturnType<typeof loader>>16
17  return (18    <div>19      <Container className="divide-y p-0">20        <div className="flex items-center justify-between px-6 py-4">21          <Heading level="h2">Products count: {products.length}</Heading>22        </div>23      </Container>24    </div>25  )26}27
28export default CustomPage

In this example, you first export a loader function that can be used to fetch data, such as products. The function returns an object with a products property.

Then, in the CustomPage route component, you use the useLoaderData hook from React Router to access the data returned by the loader function. You can then use the data in your component.

Route Parameters#

You can also access route params in the loader function. For example, consider the following UI route created at src/admin/routes/custom/[id]/page.tsx:

src/admin/routes/custom/[id]/page.tsx
1import { Container, Heading } from "@medusajs/ui"2import {3  useLoaderData,4  LoaderFunctionArgs,5} from "react-router-dom"6
7export async function loader({ params }: LoaderFunctionArgs) {8  const { id } = params9  // TODO fetch product by id10
11  return {12    id,13  }14}15
16const CustomPage = () => {17  const { id } = useLoaderData() as Awaited<ReturnType<typeof loader>>18
19  return (20    <div>21      <Container className="divide-y p-0">22        <div className="flex items-center justify-between px-6 py-4">23          <Heading level="h2">Product ID: {id}</Heading>24        </div>25      </Container>26    </div>27  )28}29
30export default CustomPage

Because the UI route has a route parameter [id], you can access the id parameter in the loader function. The loader function accepts as a parameter an object of type LoaderFunctionArgs from React Router. This object has a params property that contains the route parameters.

In the loader, you can fetch data asynchronously using the route parameter and return it. Then, in the route component, you can access the data using the useLoaderData hook.

When to Use Route Loaders#

A route loader is executed before the route is loaded. So, it will block navigation until the loader function is resolved.

Only use route loaders when the route component needs data essential before rendering. Otherwise, use the JS SDK with Tanstack (React) Query as explained in this chapter. This way, you can fetch data asynchronously and update the UI when the data is available. You can also use a loader to prepare some initial data that's used in the route component before the data is retrieved.


Other React Router Utilities#

Route Handles#

NoteRoute handles are available starting from Medusa v2.5.1.

In your UI route or any route file, you can export a handle object to define route handles. The object is passed to the loader and route contexts.

For example:

src/admin/routes/custom/page.tsx
1export const handle = {2  sandbox: true,3}

React Router Components and Hooks#

Refer to react-router-dom’s documentation for components and hooks that you can use in your admin customizations.

Was this chapter helpful?
Edit this page
Ask Anything
FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break