Interface: StorefrontProviderProps
@doswiftly/storefront-sdk/react — React adapter
Provides React providers, Zustand stores, and hooks that wrap the framework-agnostic core.
Peer dependencies: react ^18 || ^19, zustand ^5
Example
import { StorefrontProvider, useAuth, useCartManager, useCurrency } from '@doswiftly/storefront-sdk/react';
Extends
Properties
authBasePath?
optionalauthBasePath?:string
Base path of the SDK-BFF auth route handlers (default /api/auth). The
proactive scheduler and the reactive-401 renewal post to ${authBasePath}/refresh
(same-origin), which rotates the refresh cookie server-side. Override only for
non-standard mounts — it must match where createStorefrontAuthRoute is mounted.
Overrides
StorefrontClientProviderProps.authBasePath
autoRefresh?
optionalautoRefresh?:boolean
Proactive session refresh. Defaults to ON in the browser and OFF on the
server — you do NOT need to pass it. When active, the SDK renews the access
token shortly before it expires so an active buyer is never logged out
mid-session, and fires a global session-expired signal (subscribe via
useSessionExpired) when the session can no longer be kept alive. Pass
autoRefresh={false} to opt out and drive refreshing yourself.
botProtection?
optionalbotProtection?:BotProtectionTokenProvider|null
Bot protection token provider (created by StorefrontProvider)
Inherited from
StorefrontClientProviderProps.botProtection
botProtectionOperations?
optionalbotProtectionOperations?:string[]
Operations that require bot protection (from shop query)
Inherited from
StorefrontClientProviderProps.botProtectionOperations
children
children:
ReactNode
Inherited from
StorefrontClientProviderProps.children
config?
optionalconfig?:StorefrontProviderConfig
Client config. apiUrl and shopSlug are optional — when omitted they fall back
to NEXT_PUBLIC_API_URL / NEXT_PUBLIC_SHOP_SLUG, so a standard Next.js deploy is
zero-config. Pass either value to override the environment.
Inherited from
StorefrontClientProviderProps.config
cookieDebug?
optionalcookieDebug?: (event) =>void
Optional debug sink for cookie events. When provided, the currency and language stores emit a
phase: 'cookie' DebugEvent whenever their cookie is written. Wire it to the same
transport the GraphQL client uses (one shared sessionId) so cookie writes appear on the same
timeline as GraphQL operations. (Cart-id events are wired separately on the cart cookie store.)
Must be referentially stable (e.g. from a memoized module singleton) — the stores are created
once at provider mount, so a later cookieDebug swap is not observed.
Parameters
event
Returns
void
initialAccessToken?
optionalinitialAccessToken?:string|null
Server-side token seed. See CreateAuthStoreOptions.initialAccessToken
for full semantics and security guarantees (token kept in memory, never
persisted). Wire up from your Server Component with cookies() + AUTH_COOKIE_NAME.
Example
// app/layout.tsx
import { cookies } from 'next/headers';
import { AUTH_COOKIE_NAME } from '@doswiftly/storefront-sdk';
const cookieStore = await cookies();
const initialAccessToken = cookieStore.get(AUTH_COOKIE_NAME)?.value ?? null;
<StorefrontProvider initialAccessToken={initialAccessToken} ...>
initialExpiresAt?
optionalinitialExpiresAt?:string|null
Server-side session-expiry seed (ISO 8601) — typically the readable
session-expiry cookie value read in a Server Component. Lets the refresh
scheduler arm on the first render (cold start) without a whoami round-trip.
Optional — when no initial* prop is passed the provider reads the same
cookie client-side by itself (see initialIsAuthenticated).
initialIsAuthenticated?
optionalinitialIsAuthenticated?:boolean
Server-side auth hint — set to true when httpOnly auth cookie exists.
This allows the auth store to start with isAuthenticated: true on first render,
eliminating the flash of "Sign In" while Zustand persist rehydrates from localStorage.
Read from cookies() in a Server Component (layout.tsx) and pass here.
Optional. When NONE of initialIsAuthenticated / initialAccessToken /
initialExpiresAt are passed, the provider seeds itself in the browser from
the readable session-expiry cookie right after hydration — a returning
visitor's session survives a hard reload with a fully static root layout, no
cookies() read required and no hydration mismatch (the first client render
matches the server's signed-out markup; the store flips in an effect).
The access token is renewed by the refresh scheduler's cold-start recovery;
gate account reads on useAuthReady() so they wait for it. Pass any of these
props explicitly to take over seeding (and disable the cookie fallback).
Defaults to !!initialAccessToken when provided alongside a token (raw token
implies authenticated). Pass false explicitly to override in edge cases
(opt-out flow, recovery banner that holds a token without claiming auth state).
initialLanguage?
optionalinitialLanguage?:string
Server-side language hint — pass the URL locale from next-intl params. Eliminates flash of wrong language on first render by initializing the language store with the correct value from the server.
middleware?
optionalmiddleware?:Middleware[]
Additional middleware to prepend to the default pipeline. Default pipeline: auth → currency → bot-protection → [custom] → retry → timeout → errors
Inherited from
StorefrontClientProviderProps.middleware
queryAdapter?
optionalqueryAdapter?:StorefrontQueryAdapter
Register a server-state library (TanStack Query, SWR, …) so the data hooks
(useStorefrontQuery / useCustomerQuery) gain a browser-side cache through it. Omit it to
use the built-in lite engine (per-component state). The SDK clears the adapter on sign-out,
session expiry, and account switch, so one account never reads another's cache. Use a ready-made
adapter (e.g. createTanstackQueryAdapter from @doswiftly/storefront-sdk/react/tanstack) or
supply your own.
Register it once — a memoized value or module-level singleton, before children mount. The active adapter is frozen per consumer mount, so toggling it between defined/undefined at runtime takes effect only on remount (this is what keeps the data hooks rules-of-hooks safe).
sessionExpiredEmitter?
optionalsessionExpiredEmitter?:SessionExpiredEmitter
Auth-level session-expired emitter (from StorefrontProvider). When present, a reactive 401 on a read query triggers a single deduped refresh + replay, while a 401 on a mutation — or a refresh that also fails — fires this emitter.
Inherited from
StorefrontClientProviderProps.sessionExpiredEmitter
shopData
shopData:
ShopConfig