useSubscribe
The useSubscribe hook is used to subscribe a customer to a newsletter. This can either be a general subscription or a specific subscription to a product.
Usage
Use this hook in newsletter popups, newsletter banners, and back in stock notification events.
Basic Usage
NewsletterForm.tsx
import { useSubscribe } from "@frend-digital/centra/client";import { useActionState } from "react";
export const NewsletterForm = () => { const { data, mutate, isPending } = useSubscribe();
const action = (formData: FormData) => { const email = formData.get("email").toString(); if (!email) return; // Show a warning to the user here somehow
mutate({ email }); };
return ( <form action={action}> <h2>Subscribe to newsletter</h2> {data && <p>You are subscribed to the newsletter.</p>} <input name="email" type="email" required />
<button type="submit" disabled={isPending}> {isPending ? "Subscribing..." : "Subscribe"} </button> </form> );};Example: Back in stock subscription
"use client";
import { useBuyBox, type SizeItem } from "@frend-digital/centra/client";import { atom, useAtom } from "jotai";
export const backInStockModal = atom<SizeItem | null>(null);
const BackInStockForm = ({ item }: { item: SizeItem }) => { const { data, mutate, isPending } = useSubscribe(); const setItem = useSetAtom(backInStockModal);
const action = (formData: FormData) => { const email = formData.get("email").toString(); if (!email) return; // Show a warning to the user here somehow
mutate({ email, item: item.itemId }); };
const closeModal = () => setItem(null);
if (data) { // We are successfully subscribed to the newsletter return ( <div> <h2>Subscribed!</h2> <p>You will receive a notification when this item is back in stock.</p> <button onClick={closeModal}>Close</button> </div> ); }
return ( <form action={action}> <h2>Notify me when back in stock</h2> <p>We will notify you when this item is back in stock.</p> <input name="email" type="email" required /> <button type="submit" disabled={isPending}> {isPending ? "Subscribing..." : "Subscribe"} </button> </form> );};
const BackInStockModal = () => { const [item, setItem] = useAtom(backInStockModal);
// Simply close the modal here const handleClose = (open) => { if (!open) setItem(null); };
return ( <DialogRoot open={!!item} onOpenChange={handleClose}> <DialogViewport> <DialogContent> <BackInStockForm item={item} /> </DialogContent> </DialogViewport> </DialogRoot> );};"use client";
import { useBuyBox } from "@frend-digital/centra/client";import { backInStockModal } from "./BackInStockModal";import { useSetAtom } from "jotai";
export const BuyBox = ({ sizes }: { sizes: Product["items"] }) => { const openModal = useSetAtom(backInStockModal);
const { getButtonProps, getButtonLabel, getSizeProps } = useBuyBox({ sizes, labels: { add_to_cart: "Add to cart", coming_soon: "Coming soon", out_of_stock: "Out of stock", preorder: "Preorder", select_size: "Select size", }, onNotify: (type, item) => { if (type === "out_of_stock") { openModal(item); // The user has pressed "Notify me when back in stock" so we set the item to the modal } } });
return ( <section> <div> <strong>Size</strong> <div> {sizes?.map((item) => ( <a className={styles.sizeButton} key={item.sizeId} {...getSizeProps(item)} > {item.name} </a> ))} </div> </div>
<button {...getButtonProps()} className={styles.addToCart}> {getButtonLabel()} </button> </div> );};import { BuyBox } from "./BuyBox";import { BackInStockModal } from "./BackInStockModal";
const ProductPage = ({ product }: { product: Product }) => { return ( <main> <h1>{product.name}</h1> <p>{product.description}</p> <section> <BuyBox sizes={product.sizes} /> </section> <BackInStockModal /> </main> );};Anatomy
The internal workings of this hook.
type NewsletterFormData = { email: string; item?: string;}
declare function useSubscribe(): { mutate: (data: NewsletterFormData) => Promise<void>; ...UseMutationResult};