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:
Shahed Nasser
2024-06-13 12:21:54 +03:00
committed by GitHub
parent d862d03de0
commit c1db40b564
80 changed files with 2301 additions and 701 deletions
@@ -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()
// ...
}
```