React SDK
Providers, hooks, GraphQL helpers, and Next.js server utilities from @storeos/storefront-client/react.
What is the React SDK?
The React SDK is the GraphQL + React surface of @storeos/storefront-client. Use it when you want storefront providers (auth, cart), typed GraphQL helpers, and checkout form schemas — instead of wiring the REST client by hand.
It talks to https://storefront-api.storeos.dev (GraphQL at /graphql) by default.
Entry points
| Import | Use for |
|---|---|
@storeos/storefront-client/react | Client providers, hooks, GraphQL client, utils, Zod schemas |
@storeos/storefront-client/react/server | Next.js gqlServerClient + getServerSession |
@storeos/storefront-client/react/queries | Shared GraphQL documents (RSC-safe) |
@storeos/storefront-client/react/types | Enums and GraphQL-aligned types (RSC-safe) |
Install
npm install @storeos/storefront-client react react-dom @tanstack/react-query zod immer use-immer
# optional for App Router server helpers
npm install nextAuth uses React Query, so wrap your tree with QueryClientProvider and StoreOSProvider.
Setup
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { StoreOSProvider } from "@storeos/storefront-client/react";
const queryClient = new QueryClient();
export function Providers({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
<StoreOSProvider
config={{
tenant: process.env.NEXT_PUBLIC_SITE_API_TENANT!,
siteUrl: process.env.NEXT_PUBLIC_SITE_URL,
// apiUrl defaults to https://storefront-api.storeos.dev
}}
>
{children}
</StoreOSProvider>
</QueryClientProvider>
);
}StoreOSProvider calls initStoreOS(config) and mounts auth + cart context.
Config options
| Field | Default | Purpose |
|---|---|---|
tenant | — (required) | Store ID → x-tenant |
apiUrl | https://storefront-api.storeos.dev | API origin (GraphQL at /graphql) |
siteUrl | "" | Public site URL helpers |
staticFileBaseUrl | https://cdn.storeos.dev | Media / CDN base |
auth.cookieName | auth_token | Session cookie |
auth.cookieMaxAge | 30 days | Cookie max-age (seconds) |
auth.tokenPollingInterval | 2000 | Client token poll (ms) |
cart.storageKey | cart | localStorage key |
currency.code / locale | BDT / en-BD | Money formatting |
Auth
import { useAuth, useSession } from "@storeos/storefront-client/react";
function AccountMenu() {
const { session, login, logout, loading } = useAuth();
// or: const session = useSession();
if (loading) return null;
if (!session.user) {
return (
<button
onClick={() =>
login({ user: "customer@example.com", password: "••••••••" })
}
>
Sign in
</button>
);
}
return (
<div>
<span>{session.user.name ?? session.user.email}</span>
<button onClick={() => logout()}>Sign out</button>
</div>
);
}| API | What it does |
|---|---|
useAuth() | session, login, logout, refreshAuth, loading |
useSession() | { user, accessToken } only |
getAuthToken / setCookieAuthToken / removeCookieAuthToken | Cookie helpers |
Cart
Cart is stored in localStorage (not on the API). The provider tracks line items, totals, and drawer open state.
import { useCart } from "@storeos/storefront-client/react";
import type { CartLineItem } from "@storeos/storefront-client/react";
function AddToCartButton({ item }: { item: CartLineItem }) {
const { addItem, totalItems, subTotalAmount } = useCart();
return (
<button onClick={() => addItem(item)}>
Add to cart ({totalItems}) — {subTotalAmount}
</button>
);
}| API | Description |
|---|---|
lineItems | Current lines |
addItem / removeItem / adjustQuantity / clearCart | Mutate cart |
subTotalAmount / totalItems | Derived totals |
cartDrawerOpen / setCartDrawerOpen | Drawer UI state |
At checkout, map lineItems into your order mutation / form payload.
GraphQL (client)
import { useQuery } from "@tanstack/react-query";
import { gqlClient } from "@storeos/storefront-client/react";
import { PRODUCTS_QUERY } from "@storeos/storefront-client/react/queries";
function ProductGrid() {
const { data, isLoading } = useQuery({
queryKey: ["products"],
queryFn: () =>
gqlClient<{ products: { nodes: unknown[] } }>({
query: PRODUCTS_QUERY,
variables: { page: 1, limit: 24 },
}),
});
if (isLoading) return null;
return /* render data.products.nodes */;
}gqlClient attaches x-tenant and the auth cookie automatically.
Next.js server
Call initStoreOS once in a server entry (layout or shared module) before using server helpers:
import { initStoreOS } from "@storeos/storefront-client/react";
import {
getServerSession,
gqlServerClient,
} from "@storeos/storefront-client/react/server";
import { PRODUCTS_QUERY } from "@storeos/storefront-client/react/queries";
initStoreOS({
tenant: process.env.NEXT_PUBLIC_SITE_API_TENANT!,
siteUrl: process.env.NEXT_PUBLIC_SITE_URL,
});
export default async function Page() {
const session = await getServerSession();
const data = await gqlServerClient({
query: PRODUCTS_QUERY,
variables: { page: 1, limit: 12 },
});
return /* … */;
}| Helper | What it does |
|---|---|
getServerSession() | Reads auth cookie → { user, accessToken } |
gqlServerClient() | Server GraphQL fetch with tenant + cookie token |
Variant selection
import { useVariantSelection } from "@storeos/storefront-client/react";
function VariantPicker({ product }) {
const {
selectedAttributes,
setSelectedAttributes,
selectedVariant,
isOptionAvailable,
} = useVariantSelection({
variants: product.variants,
variantConfigs: product.variantConfigs,
productId: product._id,
});
// Only valid combinations are stored; impossible combos are normalized away.
}Checkout validation
Zod schemas for guest vs logged-in checkout forms:
import {
getCheckoutFormSchema,
checkoutFormSchema,
loggedInCheckoutFormSchema,
} from "@storeos/storefront-client/react";
import type { CheckoutFormData } from "@storeos/storefront-client/react";
const schema = getCheckoutFormSchema(isLoggedIn);
const parsed: CheckoutFormData = schema.parse(formValues);Utilities
import {
formatCurrency,
formatAmount,
getFileUrl,
createUrl,
getSiteUrl,
getDeliveryCharge,
calculateOrderTotal,
getDeliveryAreaDisplayName,
getVariantFromSelection,
isVariantOptionAvailable,
} from "@storeos/storefront-client/react";Queries & types
Import documents and enums without pulling client-only code (safe in Server Components):
import {
ME_QUERY,
LOGIN_MUTATION,
PRODUCTS_QUERY,
PRODUCT_BY_ID_QUERY,
SEARCH_PRODUCTS_QUERY,
COLLECTIONS_QUERY,
CREATE_ORDER_MUTATION,
MY_ORDERS_QUERY,
ORDER_DETAILS_QUERY,
CANCEL_ORDER_MUTATION,
VERIFY_COUPON_MUTATION,
STOREFRONT_QUERY,
} from "@storeos/storefront-client/react/queries";
import {
DeliveryArea,
Invoice_Payment_Method,
Invoice_Status,
ProductStatus,
} from "@storeos/storefront-client/react/types";Surface summary
| Area | Exports |
|---|---|
| Provider | StoreOSProvider, initStoreOS, getConfig |
| Auth | useAuth, useSession, cookie token helpers |
| Cart | useCart, StoreOSCartProvider |
| GraphQL | gqlClient (client); gqlServerClient, getServerSession (server) |
| Variants | useVariantSelection |
| Validation | checkoutFormSchema, loggedInCheckoutFormSchema, getCheckoutFormSchema, … |
| Utils | currency, URLs, delivery, variant helpers |
| Queries / types | …/react/queries, …/react/types |
Next steps
- TypeScript SDK overview — REST vs React
- GraphQL API — schema reference
- Checkout guide — order flow
- REST methods — if you prefer the REST client