Create Cart Context in Storefront

Throughout your storefront, you'll need to access the customer's cart to perform different actions.

So, if your storefront is React-based, create a cart context and add it at the top of your components tree. Then, you can access the customer's cart anywhere in your storefront.

Create Cart Context Provider#

For example, create the following file that exports a CartProvider component and a useCart hook:

Code
1"use client" // include with Next.js 13+2
3import { 4  createContext, 5  useContext, 6  useEffect, 7  useState,8} from "react"9import { HttpTypes } from "@medusajs/types"10import { useRegion } from "./region"11
12type CartContextType = {13  cart?: HttpTypes.StoreCart14  setCart: React.Dispatch<15    React.SetStateAction<HttpTypes.StoreCart | undefined>16  >17  refreshCart: () => void18}19
20const CartContext = createContext<CartContextType | null>(null)21
22type CartProviderProps = {23  children: React.ReactNode24}25
26export const CartProvider = ({ children }: CartProviderProps) => {27  const [cart, setCart] = useState<28    HttpTypes.StoreCart29  >()30  const { region } = useRegion()31
32  useEffect(() => {33    if (cart || !region) {34      return35    }36
37    const cartId = localStorage.getItem("cart_id")38    if (!cartId) {39      // create a cart40      fetch(`http://localhost:9000/store/carts`, {41        method: "POST",42        credentials: "include",43        headers: {44          "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "temp",45          "Content-Type": "application/json",46        },47        body: JSON.stringify({48          region_id: region.id,49        }),50      })51      .then((res) => res.json())52      .then(({ cart: dataCart }) => {53        localStorage.setItem("cart_id", dataCart.id)54        setCart(dataCart)55      })56    } else {57      // retrieve cart58      fetch(`http://localhost:9000/store/carts/${cartId}`, {59        credentials: "include",60        headers: {61          "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "temp",62        },63      })64      .then((res) => res.json())65      .then(({ cart: dataCart }) => {66        setCart(dataCart)67      })68    }69  }, [cart, region])70
71  const refreshCart = () => {72    localStorage.removeItem("cart_id")73    setCart(undefined)74  }75
76  return (77    <CartContext.Provider value={{78      cart,79      setCart,80      refreshCart,81    }}>82      {children}83    </CartContext.Provider>84  )85}86
87export const useCart = () => {88  const context = useContext(CartContext)89
90  if (!context) {91    throw new Error("useCart must be used within a CartProvider")92  }93
94  return context95}

The CartProvider handles retrieving or creating the customer's cart. It uses the useRegion hook defined in the Region Context guide.

The useCart hook returns the value of the CartContext. Child components of CartProvider use this hook to access cart, setCart, or refreshCart.


Use CartProvider in Component Tree#

To use the cart context's value, add the CartProvider high in your component tree.

For example, if you're using Next.js, add it to the app/layout.tsx or src/app/layout.tsx file:

app/layout.tsx
13
14export default function RootLayout({15  children,16}: Readonly<{17  children: React.ReactNode;18}>) {19  return (20    <html lang="en">21      <body className={inter.className}>22        <RegionProvider>23          <CartProvider>24          {/* Other providers... */}25            {children}26          </CartProvider>27        </RegionProvider>28      </body>29    </html>30  )31}

Use useCart Hook#

Now, you can use the useCart hook in child components of CartProvider.

For example:

Code
1"use client" // include with Next.js 13+2// ...3import { useCart } from "../providers/cart"4
5export default function Products() {6  const { cart } = useCart()7  // ...8}
Was this page helpful?
Edit this page