Skip to main content
This page is the curated reference. The complete, generated type reference lives at /kit/api/react and is regenerated from the published typings. For a walkthrough, start with React setup.
Every export is a client hook or client component; the entry carries a "use client" directive. React is an optional peer dependency, ^18.2 || ^19. The slug, id and promise forms of <ProductProvider>, and <SEO /> tag hoisting, need React 19. The components render no markup of their own: no wrapper, no class names. The exceptions are <ProductImage /> (one <img>), <Checkout> (one <div> holding the frame), the SEO components (head tags), and the consent banner’s default dialog and <ConsentSettingsButton> (which render only when you give them no content of your own).

Providers and context

ShopkitProvider

Makes one client and one shared CartStore available to the tree. Both are created once and kept for the provider’s lifetime. By default it also mounts cookie consent, the default banner and the shop’s own analytics, gated on the shopper’s decision (see the consent prop).
ShopkitConfig
A plain config object, which can cross a server-to-client boundary. Read once, not a render dependency. See Client.
ShopkitClient
A client you built yourself. Takes precedence over config.
Cart | null
A cart read on the server. The store starts ready, so SSR and the first client paint agree.
string | null
Sell the whole tree into one campaign storefront. Changing it rebuilds the client and the cart store. With a prebuilt client, it must match that client’s binding or it throws.
string | null
Shorthand for config.currency: the currency to browse in until the shopper picks one, so a default, not an override. A later change switches the same client with setCurrency() without rebuilding it: catalog hooks refetch and the same cart is re-read. A change to null returns to the value the provider mounted with, not necessarily the shop’s own currency; mount with no currency if null should mean the shop’s own. With a prebuilt client the mount-time value is ignored (give the client its currency) and only later changes are forwarded. See Currencies.
Shapes the cookie consent and analytics the provider mounts, which are on by default. It does not switch them off: the one switch is consent: false in the client config, which a server client’s checkout handoff reads too. consent={false} on the prop still turns consent off for this tree, but is deprecated and warns, because a server-started checkout cannot see it.A provider nested inside another (a campaign provider inside the site’s) reuses the outer consent store, banner and analytics hub. See Consent and analytics.
ReactNode
required

useShopkit / useShopkitContext

Both throw a ShopkitConfigError when there is no provider above. ShopkitContext is exported for advanced composition.

Cart

useCart

Every caller shares the same store. The cart is loaded on first mount and never created speculatively.
Cart | null
number
Sum of quantities, for a badge.
'idle' | 'loading' | 'ready' | 'error'
number
Mutations in flight.
Error | null
Captured, not thrown.
number
Bumped once per successful mutation made through the store.
Promise<Cart | null>
{ productId, variantId?, quantity? }. null on failure.
Promise<Cart | null>
Line id. 0 removes the line.
Promise<Cart | null>
Promise<void>
Deletes the remembered cart and forgets it. clearCart is an alias.
Promise<Cart | null>

Catalog hooks

All return AsyncState<T>: { data: T | null; loading: boolean; error: Error | null; refetch(): void }. Each fetch is aborted on unmount and on every re-run, and a superseded response is discarded, so a search-as-you-type box cannot land an out-of-order result. They are not a cache; an app with TanStack Query or SWR should call the client directly.

useProducts

The product hooks follow the client’s currency and refetch when it changes. A currency parameter prices one read in another currency (null for the shop’s own).

useProductSearch

Takes every products.search parameter. All are primitives, so an inline object literal does not re-fetch.

useProduct

data is null for a hidden or missing product.

useCategories

useShop

Currency

useCurrency

The currency the tree browses in, what the shop offers, and the switch. Reads the shop once per client (shared by every caller; needs checkout:read). See Currencies.
string | null
What prices are shown in: the choice when the shop offers it, else the shop’s own.
string | null
What was asked for (the remembered choice, else the configured default), whether or not the shop offers it.
string | null
The shop’s own currency.
ShopCurrency[]
{ code, mode, rate }[], base first. Only the base entry when the converter is off; empty while loading.
'base' | 'display' | 'charge'
display: shown converted, charged in the shop’s currency. charge: priced and charged in it.
number
Units of currency per 1 unit of the shop’s currency.
string | null
What the checkout will charge.
Promise<void>
Switch and remember. Every product hook refetches, useCart() re-reads the same cart, and the next checkout opens in it. null returns to the default.
boolean
True while the shop, and with it the list of currencies, is loading.
Error | null

useClientCurrency

The bare subscription: client.currency, re-rendering when it changes. No shop read.

useAsync

The primitive the catalog hooks are built on, for a read of your own with the same abort semantics.

Product and variant selection

ProductProvider

Holds the variant selection for one product and derives everything from it. Renders nothing of its own. A slug or id lookup re-reads the product when the client’s currency changes. With analytics on, it tracks view_item once per product.
Product | Promise<Product | null> | null
A resolved product, or a promise unwrapped with React 19 use() (wrap in <Suspense>). Takes precedence over slug and id.
string
Looks the product up. Walks the catalog; needs React 19 and a <ShopkitProvider>.
string | number
Looks the product up by id. Needs React 19 and a <ShopkitProvider>.
ReactNode
Rendered when the product is missing or hidden.
number
Preselect a variant, for ?variant= deep links.
boolean
default:"false"
Start on the first non-hidden variant instead of a price range.
string
A formatting fallback, used only when the product does not state its own product.currency (a platform older than the field). Passed through to useProductPrice and <SEO />.
(variant: ProductVariant | null) => void
ReactNode
required

useProductState

Product
VariantOptionGroupState[]
Each group with its values, selected and available.
Record<number, number>
ProductVariant | null
boolean
The selection pins one variant.
boolean
VariantPriceState
amount, compareAtAmount, min, max, isRange.
string | undefined
The product’s own product.currency, else the provider’s currency prop. Format with this.
void
Repairs contradictions instead of refusing.
void
void
void

Selection hooks

useProductAddToCart

Promise<Cart | null>
Adds the selected variant. A no-op while the selection is incomplete.
boolean
False until one variant is pinned, while a mutation is in flight, and during a buy-now.
number
Error | null
VariantOptionGroupState[]
The groups still missing a choice, for a “Select a size” prompt.
Promise<void>
Adds the selected variant and navigates to the hosted checkout. input is a StartCheckoutInput.
boolean
True while a buy-now runs, and after it navigated until the page is restored.
Error | null

Headless components

Each renders only what its children function returns. fallback renders when the product has no such group, so a component written for “Color” degrades quietly.

Images

ProductImage

Renders a single <img> with the CDN URL and srcSet resolved. Product precedence: image, product, the surrounding <ProductProvider>, then a lookup by productId or slug.
number
CSS pixels. Drives the resize, the srcSet and the box.
number
number
default:"0"
Which image, in display order.
number
A specific image, for example variant.imageId.
number[]
default:"[1, 2]"
[] disables the srcSet.
number[]
w descriptors instead; pair with sizes.
ImageTransform
quality, format, fit, crop and so on.
string
Defaults to the image’s alt text, then the product name, then "".
ReactNode
Rendered when there is no image. Never a broken <img>.
boolean
loading="eager" and fetchPriority="high", for the LCP image. Everything else lazy-loads.
boolean
default:"false"
boolean
default:"true"
various
Which product and image; see above.
Every other <img> attribute passes through.

useProductImage

The same resolution without rendering, for next/image, a CSS background or an og:image.

Checkout

useCheckout

Promise<StartCheckoutResult | null>
Creates the session without navigating.
Promise<void>
Creates the session and navigates with location.assign.
Promise<void>
Adds one item to the remembered cart and navigates.
boolean
True while starting, and after a navigation until the page is restored from the back/forward cache. A navigation that never unloads releases it after 10 seconds.
Error | null
string | null
The last handoff URL.
A second click while one is in flight is ignored. input is a StartCheckoutInput; pass cartId: cart?.id from useCart() where cookies may be blocked (an app builder’s preview).

useOrderConfirmation

Polls until the order exists, the payment fails terminally, or the caps are reached. Without a sessionId it uses the one the kit remembered when the checkout started. With analytics on, a completed order is reported as the purchase event once, deduplicated across reloads.
boolean
default:"true"
false never polls.
SessionConfirmation | null
The snapshot the server already took with shopkit.checkout.confirmation(). A completed or failed one is final: nothing is polled, the bought cart and session are forgotten (as a completed poll does), and a completed one is reported as the purchase. A pending one is polled from.
boolean
default:"true"
Report the purchase event once the order exists.
'completed' | 'processing_payment' | 'no_attempt' | 'failed' | null
number | null
ConfirmationOutcome | null
timeout is not a failure.
SessionConfirmation | null
boolean
Error | null
For example “no checkout session to confirm” on a direct visit.

Checkout

The hosted checkout rendered inline in an iframe. Renders one <div> with the frame inside. The session is created once, on mount; changing props afterwards does not rebuild it. It follows the cart: nothing mounts for an empty cart, and emptying the cart takes the frame down. See Embedded checkout.
string
Relative URLs resolve against the page. Only the origin is used for the landing.
string
string
'light' | 'dark'
Omitted, the checkout follows the merchant’s setting.
'redirect' | 'inline'
default:"redirect"
number
default:"600"
string
CSSProperties
(detail: { sessionId, shopId, step }) => void
(detail: { step }) => void
(detail: { name, params }) => void
(detail: { sessionId, orderNumber, successUrl }) => void
(detail: { code, message, fatal }) => void
A checkout that could not start is reported here, never thrown.
(detail: { reason, url }) => void
() => void
Called once when the cart settles empty.
<ShopkitProvider> mounts all of this by default; the pieces are public for a page that composes them itself. See Consent and analytics.

ConsentProvider

Provides one consent store to the tree. Takes every ConsentStoreOptions field (revision, cookieName, maxAgeDays, domain, sameSite, secure, persist, initialState), plus store (a ConsentStore you built, for example one bridged to a third-party consent platform with persist: false) and lang. A <ConsentProvider> inside one that already exists shares the existing store: one decision per page.

useConsent / useOptionalConsent

'undecided' | 'decided'
Undecided is treated as denied.
boolean
boolean
The preferences panel is open.
boolean
"necessary" is always allowed.
void
void
{ analytics, marketing }.
void
Withdraw: forget the decision and show the banner again.
void
ConsentStore
useConsent() throws without a consent provider above.

ConsentBanner

With no children it renders the kit’s styled, accessible dialog; with a render function it renders only what you return. A banner you place replaces the provider’s default one.
(state: ConsentBannerState) => ReactNode
state is the consent snapshot plus visible, labels, draft, setDraft(partial), acceptAll, rejectAll, save (saves the draft), reset, openSettings, closeSettings.
string | null
Partial<ConsentLabels> | null
string | null
string
boolean
Leave out the stylesheet.
boolean
Keep it visible after a decision.
visible is true while undecided, while the preferences panel is open, or with showWhenDecided. The banner renders nothing before hydration unless the provider got initialState.

ConsentSettingsButton

A real <button type="button"> that reopens the banner’s preferences, for a footer. Labelled “Cookie settings” in the provider’s lang when given no children. Takes every <button> attribute plus lang.

ConsentGate

Renders children only once category is allowed, fallback until then.

AnalyticsProvider

The analytics hub, gated on the consent store above. <ShopkitProvider> mounts one by default; an explicit one inside it joins that hub (its destinations are added) instead of loading the pixels twice.
AnalyticsDestination[]
Destinations of your own, on top of (or with auto: false, instead of) the shop’s.
boolean
default:"true"
Load the merchant’s GA4, GTM and Meta pixel from shop.tracking.
false runs analytics ungated, and makes the hosted checkout track ungated too. Only for a storefront that owes its shoppers no consent.
Load GTM or gtag.js before the shopper decides, under a Consent Mode default of everything denied. A GTM container loaded this way runs all of its tags.
string
The currency for events that carry none. Falls back to the cart’s.
string | number | null
The shop’s numeric store id, for the purchase dedup key and Meta’s eventID. Learned from the cart when omitted.
number
default:"50"
Events remembered for destinations not ready yet. Minimum 1.
boolean
Log every dispatch.

useAnalytics / useOptionalAnalytics

The Analytics hub. See Utilities for its methods and the event builders.

useTrackPurchase

Reports the purchase for an order number you already have, from the checkout session’s lines and total. Deduplicated per order across page loads, so it never double-counts beside useOrderConfirmation. Pass sessionId explicitly when useOrderConfirmation runs on the same page, because its completed poll forgets the remembered session. tracked is true once reported, here or on an earlier visit.

SEO

See SEO.

SeoProvider

Takes every SeoDefaults field: baseUrl, siteName, titleTemplate, locale, defaultImage, twitterSite, twitterCreator, currency, productPath, categoryPath, shop, organization. useSeoDefaults() reads them back.

SEO

Renders the title, meta tags, canonical, OpenGraph, Twitter card and JSON-LD. Takes every SeoInput and SeoDefaults field, plus skipTitle and skipJsonLd. React 19 hoists the tags into <head>; on React 18 use useSeo() with your framework’s head.

useSeo

JsonLd

Renders <script type="application/ld+json"> for one node or many. For Next.js generateMetadata pages, whose metadata has no JSON-LD slot.

CartStore

CartStore and its CartSnapshot type are exported from this entry. See Cart. So are ConsentStore, Analytics and the consent and analytics types (ConsentState, ConsentSnapshot, ConsentCategory, ConsentChoice, ConsentLabels, AnalyticsDestination, CommerceEvent, CommerceItem, PurchaseEvent), so a React app needs no second import.