Create Cart Context in Storefront

In this guide, you'll learn how to create a cart context in your storefront.

Why Create a Cart Context?#

Throughout your storefront, you'll need to access the customer's cart to perform different actions. For example, you may need to add a product variant to the cart from the product page.

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:

Tip
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"11import { sdk } from "@/lib/sdk"12
13type CartContextType = {14  cart?: HttpTypes.StoreCart15  setCart: React.Dispatch<16    React.SetStateAction<HttpTypes.StoreCart | undefined>17  >18  refreshCart: () => void19}20
21const CartContext = createContext<CartContextType | null>(null)22
23type CartProviderProps = {24  children: React.ReactNode25}26
27export const CartProvider = ({ children }: CartProviderProps) => {28  const [cart, setCart] = useState<29    HttpTypes.StoreCart30  >()31  const { region } = useRegion()32
33  useEffect(() => {34    if (cart || !region) {35      return36    }37
38    const cartId = localStorage.getItem("cart_id")39    if (!cartId) {40      // create a cart41      sdk.store.cart.create({42        region_id: region.id,43      })44      .then(({ cart: dataCart }) => {45        localStorage.setItem("cart_id", dataCart.id)46        setCart(dataCart)47      })48    } else {49      // retrieve cart50      sdk.store.cart.retrieve(cartId)51      .then(({ cart: dataCart }) => {52        setCart(dataCart)53      })54    }55  }, [cart, region])56
57  const refreshCart = () => {58    localStorage.removeItem("cart_id")59    setCart(undefined)60  }61
62  return (63    <CartContext.Provider value={{64      cart,65      setCart,66      refreshCart,67    }}>68      {children}69    </CartContext.Provider>70  )71}72
73export const useCart = () => {74  const context = useContext(CartContext)75
76  if (!context) {77    throw new Error("useCart must be used within a CartProvider")78  }79
80  return context81}

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

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

refreshCart unsets the cart, which triggers the useEffect callback to create a cart. This is useful when the customer logs in or out, or after the customer places an order.

Tip

You can add to the context and provider other functions useful for updating the cart and its items. Refer to the following guides for details on how to implement these functions:


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}

Make sure to put the CartProvider as a child of the RegionProvider since it uses the useRegion hook defined in the Region Context guide.

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}

The useCart hook returns the cart details, which you can use in your components.

Was this page helpful?
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