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:
- This example uses the
useRegion
hook defined in the Region React Context guide to associate the cart with the customer's selected region. - Learn how to install and configure the JS SDK in the JS SDK documentation.
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.
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:
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:
The useCart
hook returns the cart details, which you can use in your components.