Skip to main content

Introduction

The Medusa data provider enables you to build Refine applications with Medusa, a set of commerce tools and modules that can be used to build unique commerce experiences.

Installation

Install the Medusa data provider package:
npm install @refinedev/medusa

Setup

1

Set up Medusa backend

First, set up a Medusa backend following the Medusa documentation.
2

Configure data provider

Configure the Refine app with the Medusa data provider:
import { Refine } from "@refinedev/core";
import dataProvider from "@refinedev/medusa";

const App = () => {
  return (
    <Refine
      dataProvider={dataProvider("https://api.example.com")}
    >
      {/* Your app content */}
    </Refine>
  );
};

Basic Usage

Get List

Fetch a list of resources from Medusa:
import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "products",
  pagination: {
    current: 1,
    pageSize: 10,
  },
  sorters: [
    {
      field: "created_at",
      order: "desc",
    },
  ],
});

Get One

Fetch a single resource by ID:
import { useOne } from "@refinedev/core";

const { data } = useOne({
  resource: "products",
  id: "prod_123",
});

Create

Create a new resource:
import { useCreate } from "@refinedev/core";

const { mutate } = useCreate();

const handleSubmit = (values) => {
  mutate({
    resource: "products",
    values: {
      title: values.title,
      description: values.description,
      handle: values.handle,
    },
  });
};

Update

Update an existing resource:
import { useUpdate } from "@refinedev/core";

const { mutate } = useUpdate();

const handleUpdate = (id, values) => {
  mutate({
    resource: "products",
    id,
    values: {
      title: values.title,
      description: values.description,
    },
  });
};

Delete

Delete a resource:
import { useDelete } from "@refinedev/core";

const { mutate } = useDelete();

const handleDelete = (id) => {
  mutate({
    resource: "products",
    id,
  });
};

Authentication

The Medusa data provider includes built-in authentication support:
import { Refine } from "@refinedev/core";
import dataProvider, { authProvider } from "@refinedev/medusa";

const API_URL = "https://api.example.com";

const App = () => {
  return (
    <Refine
      dataProvider={dataProvider(API_URL)}
      authProvider={authProvider(API_URL)}
    >
      {/* Your app content */}
    </Refine>
  );
};

Login

import { useLogin } from "@refinedev/core";

const { mutate: login } = useLogin();

const handleLogin = (email, password) => {
  login({ email, password });
};

Logout

import { useLogout } from "@refinedev/core";

const { mutate: logout } = useLogout();

const handleLogout = () => {
  logout();
};

Working with Products

List Products

import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "products",
  filters: [
    {
      field: "status",
      operator: "eq",
      value: "published",
    },
  ],
});

Product Variants

import { useOne } from "@refinedev/core";

const { data: product } = useOne({
  resource: "products",
  id: "prod_123",
});

// Access variants
const variants = product?.data?.variants;

Product Images

import { useUpdate } from "@refinedev/core";

const { mutate } = useUpdate();

const handleAddImages = (productId, imageUrls) => {
  mutate({
    resource: "products",
    id: productId,
    values: {
      images: imageUrls.map((url) => ({ url })),
    },
  });
};

Managing Orders

List Orders

import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "orders",
  filters: [
    {
      field: "status",
      operator: "eq",
      value: "pending",
    },
  ],
  sorters: [
    {
      field: "created_at",
      order: "desc",
    },
  ],
});

Update Order Status

import { useUpdate } from "@refinedev/core";

const { mutate } = useUpdate();

const handleUpdateStatus = (orderId, status) => {
  mutate({
    resource: "orders",
    id: orderId,
    values: {
      status,
    },
  });
};

Managing Customers

List Customers

import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "customers",
  pagination: {
    current: 1,
    pageSize: 20,
  },
});

Customer Details

import { useOne } from "@refinedev/core";

const { data: customer } = useOne({
  resource: "customers",
  id: "cus_123",
});

// Access customer orders
const orders = customer?.data?.orders;

Inventory Management

Update Inventory

import { useUpdate } from "@refinedev/core";

const { mutate } = useUpdate();

const handleUpdateInventory = (variantId, quantity) => {
  mutate({
    resource: "variants",
    id: variantId,
    values: {
      inventory_quantity: quantity,
    },
  });
};

Regions and Shipping

List Regions

import { useList } from "@refinedev/core";

const { data: regions } = useList({
  resource: "regions",
});

Shipping Options

import { useList } from "@refinedev/core";

const { data: shippingOptions } = useList({
  resource: "shipping-options",
  filters: [
    {
      field: "region_id",
      operator: "eq",
      value: "reg_123",
    },
  ],
});

Complete Example

import { Refine } from "@refinedev/core";
import dataProvider, { authProvider } from "@refinedev/medusa";
import routerProvider from "@refinedev/react-router";
import { BrowserRouter } from "react-router";

const API_URL = process.env.REACT_APP_MEDUSA_API_URL!;

const App = () => {
  return (
    <BrowserRouter>
      <Refine
        dataProvider={dataProvider(API_URL)}
        authProvider={authProvider(API_URL)}
        routerProvider={routerProvider}
        resources={[
          {
            name: "products",
            list: "/products",
            create: "/products/create",
            edit: "/products/edit/:id",
            show: "/products/show/:id",
          },
          {
            name: "orders",
            list: "/orders",
            show: "/orders/show/:id",
          },
          {
            name: "customers",
            list: "/customers",
            show: "/customers/show/:id",
          },
        ]}
      >
        {/* Your routes and pages */}
      </Refine>
    </BrowserRouter>
  );
};

export default App;

Admin Dashboard Example

Here’s a complete admin dashboard example:
import { useList } from "@refinedev/core";

const Dashboard = () => {
  const { data: products } = useList({
    resource: "products",
    meta: { select: "count" },
  });

  const { data: orders } = useList({
    resource: "orders",
    filters: [
      {
        field: "created_at",
        operator: "gte",
        value: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
      },
    ],
  });

  const { data: customers } = useList({
    resource: "customers",
    meta: { select: "count" },
  });

  return (
    <div>
      <h1>Dashboard</h1>
      <div>
        <div>Total Products: {products?.total}</div>
        <div>Orders This Week: {orders?.data?.length}</div>
        <div>Total Customers: {customers?.total}</div>
      </div>
    </div>
  );
};

Filtering

Medusa supports various filter operators:
import { useList } from "@refinedev/core";

const { data } = useList({
  resource: "products",
  filters: [
    {
      field: "title",
      operator: "contains",
      value: "shirt",
    },
    {
      field: "status",
      operator: "eq",
      value: "published",
    },
  ],
});

Supported Resources

The Medusa data provider supports the following resources:
  • products: Product management
  • orders: Order management
  • customers: Customer management
  • variants: Product variants
  • regions: Regional settings
  • shipping-options: Shipping configuration
  • collections: Product collections
  • discounts: Discount management
  • gift-cards: Gift card management

Next Steps

Data Providers Overview

Learn about other data providers

Medusa Documentation

Explore Medusa features

Build docs developers (and LLMs) love