docs: added customer storefront guides (#7685)
* added customer guides * fixes to sidebar * remove old customer registration guide * fix build error * generate files * run linter
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
export const metadata = {
|
||||
title: `Customer Context in Storefront`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
Throughout your storefront, you'll need to access the logged-in customer to perform different actions, such as associate it with a cart.
|
||||
|
||||
So, if your storefront is React-based, create a customer context and add it at the top of your components tree. Then, you can access the logged-in customer anywhere in your storefront.
|
||||
|
||||
## Create Customer Context Provider
|
||||
|
||||
For example, create the following file that exports a `CustomerProvider` component and a `useCustomer` hook:
|
||||
|
||||
export const highlights = [
|
||||
["12", "customer", "Expose customer to children of the context provider."],
|
||||
["13", "setCustomer", "Allow the context provider's\nchildren to change the logged-in customer."],
|
||||
["24", "CustomerProvider", "The provider component to use in your component tree."],
|
||||
["36", "fetch", "Try to retrieve the customer's details,\nif the customer is authentiated."],
|
||||
["37", `credentials: "include"`, "Important to include this option for cookie session authentication.\nFor token authentication, pass the authorization header instead."],
|
||||
["58", "useCustomer", "The hook that child components of the provider use to access the customer."]
|
||||
]
|
||||
|
||||
```tsx highlights={highlights}
|
||||
"use client" // include with Next.js 13+
|
||||
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
type CustomerContextType = {
|
||||
customer: HttpTypes.StoreCustomer | undefined
|
||||
setCustomer: React.Dispatch<
|
||||
React.SetStateAction<HttpTypes.StoreCustomer | undefined>
|
||||
>
|
||||
}
|
||||
|
||||
const CustomerContext = createContext<CustomerContextType | null>(null)
|
||||
|
||||
type CustomerProviderProps = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export const CustomerProvider = ({
|
||||
children,
|
||||
}: CustomerProviderProps) => {
|
||||
const [customer, setCustomer] = useState<
|
||||
HttpTypes.StoreCustomer
|
||||
>()
|
||||
|
||||
useEffect(() => {
|
||||
if (customer) {
|
||||
return
|
||||
}
|
||||
|
||||
fetch(`http://localhost:9000/store/customers/me`, {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then(({ customer }) => {
|
||||
setCustomer(customer)
|
||||
})
|
||||
.catch((err) => {
|
||||
// customer isn't logged in
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<CustomerContext.Provider value={{
|
||||
customer,
|
||||
setCustomer,
|
||||
}}>
|
||||
{children}
|
||||
</CustomerContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useCustomer = () => {
|
||||
const context = useContext(CustomerContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useCustomer must be used within a CustomerProvider")
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
```
|
||||
|
||||
The `CustomerProvider` handles retrieving the authenticated customer from the Medusa application.
|
||||
|
||||
The `useCustomer` hook returns the value of the `CustomerContext`. Child components of `CustomerProvider` use this hook to access `customer` or `setCustomer`.
|
||||
|
||||
---
|
||||
|
||||
## Use CustomerProvider in Component Tree
|
||||
|
||||
To use the customer context's value, add the `CustomerProvider` 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:
|
||||
|
||||
```tsx title="app/layout.tsx" collapsibleLines="1-14" highlights={[["24"]]}
|
||||
import type { Metadata } from "next"
|
||||
import { Inter } from "next/font/google"
|
||||
import "./globals.css"
|
||||
import { CartProvider } from "../providers/cart"
|
||||
import { RegionProvider } from "../providers/region"
|
||||
import { CustomerProvider } from "../providers/customer"
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] })
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>
|
||||
<RegionProvider>
|
||||
<CustomerProvider>
|
||||
{/* Other providers... */}
|
||||
<CartProvider>
|
||||
{children}
|
||||
</CartProvider>
|
||||
</CustomerProvider>
|
||||
</RegionProvider>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Use useCustomer Hook
|
||||
|
||||
Now, you can use the `useCustomer` hook in child components of `CustomerProvider`.
|
||||
|
||||
For example:
|
||||
|
||||
```tsx
|
||||
"use client" // include with Next.js 13+
|
||||
// ...
|
||||
import { useCustomer } from "../providers/customer"
|
||||
|
||||
export default function Profile() {
|
||||
const { customer } = useCustomer()
|
||||
// ...
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user