Documentation
Feedback
Guides
Storefront Development

Storefront Development
Storefront development

FastStore hooks

Guide for all FastStore hooks, including their types, use cases, and impact on your store customization.

FastStore provides React hooks that give you access to built-in store features and state management, so you can build customized storefronts faster. This guide covers all available hooks, their categories, implementation patterns, and impact on your store.
FastStore hooks follow React's hooks conventions and allow you to:
  • Access store state: Retrieve and manage cart, session, and UI state.
  • Implement analytics: Track user behavior with GA4-compatible events.
  • Build interactive user interfaces: Create carousels, modals, search interfaces, and more.
  • Enhance accessibility: Implement focus management, keyboard navigation, and ARIA attributes.
  • Optimize performance: Lazy-load data, prefetch resources, and manage rendering.

Benefits of using FastStore hooks

FastStore hooks reduce the time and complexity of building a custom storefront by giving you direct access to core store features, state, and analytics through React-friendly APIs. The following table summarizes the main benefits hooks bring to your store development:
AreaHow hooks help
Faster developmentPre-built functionality reduces implementation time and removes the need for repetitive setup code.
ConsistencyStandardized patterns across your store keep the codebase predictable and easier to maintain.
MaintainabilityUpdates to core hooks automatically benefit your custom components, reducing manual upkeep.
AccessibilityBuilt-in accessibility features (focus management, ARIA support) help ensure compliance with WCAG standards.
Analytics integrationSeamless GA4 event tracking is available without manual instrumentation.
Type safetyFull TypeScript support with type definitions for safer customization.
Component overridesHooks let you override native components while preserving core functionality.
Custom sectionsBuild new CMS sections with full access to store data and features.
Extended behaviorAdd custom logic on top of existing features without breaking core functionality.
State managementAccess global store state without needing additional state-management libraries.

Available hooks

FastStore hooks are organized into the following categories:
Hook categoriesDescription
UI and interaction hooksAvailable from the @faststore/components package. These hooks manage user interface state and interactions.
Analytics hooksAvailable from the @faststore/core package. These hooks enable tracking and analytics integration.
Experimental hooksAvailable from the @faststore/core/experimental package. These hooks provide advanced features but are suffixed with _unstable because they may change in future releases.

UI and interaction hooks

HookDescriptionUse cases
UIProviderContext provider that manages global UI state for the cart sidebar, modals, navigation, filters, toasts, popovers, and region selection.Wrap your application root to enable UI state management. Required by other UI hooks.
useUIAccess global UI state and actions managed by UIProvider.Control the cart sidebar, modals, navigation menu, filters, toasts, popovers, and region selection from any component.
useSearchManages search interface state within the SearchProvider context.Building custom search components, managing search input state, implementing search suggestions.
useSliderManages carousel/slider state including the current page, navigation, and swipe gestures.Creating product carousels, image galleries, testimonial sliders, or any multi-item navigation component.
useSlideVisibilityDetermines visibility state for slider items based on the current index.Lazy-loading carousel images, applying visibility-based animations, optimizing render performance.
useOnClickOutsideDetects clicks outside a referenced element and triggers a callback.Closing modals when clicking backdrop, dismissing dropdowns, hiding popovers on outside interaction.
useTrapFocusTraps keyboard focus within a container element for accessibility.Modal dialogs, slide-out panels, any overlay that should constrain focus for keyboard navigation.
useScrollDirectionDetects scroll direction (up/down) for responsive header behavior.Hide/show sticky headers on scroll, trigger animations based on scroll direction, optimize mobile screen space.
useFadeEffectCreates a progressive fade-in effect based on scroll position or distance.Subtle entrance animations, progressive content reveal, enhancing visual hierarchy.
useSKUMatrixManages SKU/variant selection logic within the SKUMatrixProvider context.Building custom variant selectors, product configuration interfaces, size/color pickers.
useProductComparisonManages product comparison list within the ProductComparisonProvider.Product comparison features, "Compare" buttons on product cards, comparison page implementation.

Analytics hooks

HookDescriptionUse cases
usePageViewEventSends GA4 page view events automatically on route changes.Track page navigation, monitor user journey, required for GA4 analytics dashboards.
useViewItemListEventSends GA4 product list impression events for Product Listing Page (PLP)/search results.Product listing pages, search results, category pages, recommendation carousels to track product impressions.

Experimental hooks (unstable)

All experimental hooks are suffixed with _unstable and may change in future releases. Always test them thoroughly before deploying to production.

Authentication

HookDescriptionUse cases
useAuth_unstableManages user authentication state and actions.Login/logout functionality, protected routes, personalized content.

Cart

HookDescriptionUse cases
cartStore_unstableStore instance for cart state management (not a hook, but a store object).Direct cart state manipulation, accessing cart data outside React components.
useCart_unstableAccess current cart state reactively.Display cart summary, show item count, calculate totals in any component.
useBuyButton_unstableProvides buy button functionality with cart integration and analytics.Creating custom "Add to Cart" buttons with automatic analytics tracking and cart sidebar integration.
useCartToggleButton_unstableToggles cart sidebar visibility.Cart icon buttons, mini-cart toggles in header/navigation.
useCheckoutButton_unstableProvides checkout button functionality with validation and navigation.Cart page checkout buttons, mini-cart proceed to checkout, custom checkout flows.
useRemoveButton_unstableRemoves items from cart with analytics tracking.Cart item removal, mini-cart management, order review pages.

Delivery promise

HookDescriptionUse cases
deliveryPromiseStore_unstableStore for delivery promise data including pickup points and delivery options.Accessing delivery data across components without prop drilling.
useDeliveryPromise_unstableAccess and manage delivery promise state, pickup points, and delivery options.Shipping calculators, delivery date displays, pickup point selectors, store locators.

GraphQL

HookDescriptionUse cases
useQuery_unstableExecute GraphQL queries with automatic caching and error handling.Fetching product data, custom data requirements, extending FastStore API.
useLazyQuery_unstableExecute GraphQL queries on-demand (ex.: when a button is clicked).Search suggestions on input, load-more pagination, conditional data fetching.

Newsletter

HookDescriptionUse cases
useNewsletter_unstableNewsletter subscription functionality.Newsletter signup forms, email capture modals, footer subscription widgets.

Product

HookDescriptionUse cases
useDiscountPercent_unstableCalculate discount percentage from the price and list price.Display discount badges, savings indicators, promotional information.
useFormattedPrice_unstableFormat price values according to the current locale and currency.Display prices consistently across the store with proper currency symbols and formatting.
useLocalizedVariables_unstableProvides localized variables for queries based on the current session.Multi-locale stores, currency conversion, region-specific content.
useProductQuery_unstableFetch detailed product data by ID or slug.Product detail pages, quick view modals, product preview cards.
useProductLink_unstableGenerate SEO-friendly product URLs.Product card links, navigation to Product Detail Pages (PDPs), breadcrumbs.
useProductsPrefetch_unstablePreload product data for faster navigation.Hover intent on product cards, carousel pre-loading, performance optimization.
useProductGalleryQuery_unstableFetch product gallery images with optimization.Product image galleries, zoom functionality, image carousels.
useGalleryPage_unstableManage gallery pagination and navigation.Product image galleries, media viewers, image sliders.
useCreateUseGalleryPage_unstableCreate custom gallery page hooks with specific configurations.Advanced gallery implementations, custom pagination logic.

Search

HookDescriptionUse cases
useFilter_unstableManage search filters and facets.Product listing filters, search result refinement, faceted navigation.
useDelayedFacets_unstableDebounce facet updates to improve performance.High-traffic PLPs, complex filter combinations, performance optimization.
useDelayedPagination_unstableDebounce pagination to improve performance.Large product catalogs, infinite scroll implementations, performance-critical pages.
useSearchHistory_unstableAccess user's recent search queries.Search autocomplete, recent searches display, search suggestions.
useSuggestions_unstableProvide search term suggestions.Autocomplete dropdowns, search as you type, query assistance.
useTopSearch_unstableRetrieve popular search terms.Trending searches, search landing page, discovery features.

Session

HookDescriptionUse cases
sessionStore_unstableStore instance for session data (locale, currency, user info).Direct session manipulation, accessing session data outside React components.
useSession_unstableAccess current session data reactively.Personalized content, currency display, shipping calculations, user-specific features.
validateSession_unstableValidate and refresh session data.Session management, token refresh flows, authentication state sync.

Shipping

HookDescriptionUse cases
getShippingSimulation_unstableGet shipping simulation data (function, not a hook).Server-side shipping calculations, initial page load data, static generation.
useShippingSimulation_unstableRun shipping simulations client-side.Shipping calculators, delivery estimate displays, cart shipping options, postal code input.

UI

HookDescriptionUse cases
useScreenResize_unstableDetect screen size changes and breakpoints.Responsive behavior, mobile/desktop switching, conditional rendering based on screen size.

Hook usage guidelines

Follow these guidelines to get the most out of FastStore hooks and keep your customizations stable and maintainable.

Choose the right hook for each use case

FastStore hooks are organized by responsibility. Choosing the appropriate package for the task simplifies your code and minimizes the risk of unintended side effects:
  • UI state: Use @faststore/components hooks for interface interactions.
  • Business logic: Use @faststore/core/experimental hooks for store features.
  • Analytics: Use analytics hooks for tracking.
  • Data fetching: Use GraphQL hooks for custom queries.

Test experimental hooks before production

Experimental hooks (suffixed with _unstable) provide early access to new features but may change without notice. Before relying on them in production, take the following precautions:
  • Test in a development environment first.
  • Monitor for console warnings.
  • Check the changelog for breaking changes.
  • Have fallback behavior in place.

Common use cases

The following examples show how to combine multiple hooks to build common storefront features.

Building a custom buy button

This example builds a custom "Add to Cart" button that integrates with FastStore's cart and UI systems. It combines two hooks:
  • useBuyButton_unstable: Handles the cart logic and triggers GA4 analytics automatically when the item is added.
  • useUI: Exposes UI actions such as pushToast, used here to display a confirmation message after the user clicks the button.
The result is a fully functional buy button with built-in analytics and user feedback, without having to manually manage cart state or events.

_30
import { useBuyButton_unstable as useBuyButton } from '@faststore/core/experimental'
_30
import { useUI } from '@faststore/components'
_30
_30
function CustomBuyButton({ product, quantity = 1 }) {
_30
const { pushToast } = useUI()
_30
_30
const cartItem = {
_30
itemOffered: product,
_30
quantity,
_30
price: product.offers.offers[0].price,
_30
listPrice: product.offers.offers[0].listPrice,
_30
seller: product.offers.offers[0].seller
_30
}
_30
_30
const buyProps = useBuyButton(cartItem, true)
_30
_30
const handleClick = (e) => {
_30
buyProps.onClick(e)
_30
pushToast({
_30
message: `${product.name} added to cart!`,
_30
status: 'INFO'
_30
})
_30
}
_30
_30
return (
_30
<button {...buyProps} onClick={handleClick} className="custom-buy-button">
_30
Add {quantity} to Cart
_30
</button>
_30
)
_30
}

Creating an accessible search modal

This example creates a search modal that follows accessibility best practices (focus trapping, keyboard navigation, and dismiss-on-outside-click) while displaying search suggestions in real time. It combines four hooks:
  • useUI: Manages modal visibility and exposes the closeModal action.
  • useOnClickOutside: Closes the modal when the user clicks outside it.
  • useTrapFocus: Keeps keyboard focus inside the modal while it's open, an essential accessibility behavior for dialogs.
  • useSuggestions_unstable: Fetches search term suggestions based on the current query.

_36
import { useRef, useState } from 'react'
_36
import { useOnClickOutside, useTrapFocus, useUI } from '@faststore/components'
_36
import { useSuggestions_unstable as useSuggestions } from '@faststore/core/experimental'
_36
_36
function SearchModal() {
_36
const { modal, closeModal } = useUI()
_36
const [query, setQuery] = useState('')
_36
const ref = useRef(null)
_36
const suggestions = useSuggestions({ query })
_36
_36
useOnClickOutside(ref, closeModal)
_36
useTrapFocus(ref, { active: modal })
_36
_36
if (!modal) return null
_36
_36
return (
_36
<div role="dialog" aria-modal="true" aria-label="Search">
_36
<div ref={ref}>
_36
<input
_36
type="search"
_36
value={query}
_36
onChange={(e) => setQuery(e.target.value)}
_36
placeholder="Search products..."
_36
autoFocus
_36
/>
_36
{suggestions.length > 0 && (
_36
<ul role="listbox">
_36
{suggestions.map(item => (
_36
<li key={item.id} role="option">{item.name}</li>
_36
))}
_36
</ul>
_36
)}
_36
</div>
_36
</div>
_36
)
_36
}

This example builds a product carousel that tracks which products are visible to the shopper at any given moment, sending a GA4 view_item_list event whenever the visible set changes. It combines three hooks:
  • useSlider: Manages carousel state, navigation, and swipe gestures.
  • useSlideVisibility: Determines which items are currently visible, useful for lazy-loading and impression tracking.
  • useViewItemListEvent: Sends the GA4 product impression event with the visible products.

_52
import { useSlider, useSlideVisibility } from '@faststore/components'
_52
import { useViewItemListEvent } from '@faststore/core'
_52
import { useEffect } from 'react'
_52
_52
function ProductCarousel({ products, listName }) {
_52
const { handlers, sliderState, slide } = useSlider({
_52
totalItems: products.length,
_52
itemsPerPage: 4,
_52
infiniteMode: true
_52
})
_52
_52
const isVisible = useSlideVisibility(sliderState.currentItem, products.length)
_52
const viewItemList = useViewItemListEvent()
_52
_52
useEffect(() => {
_52
const visibleProducts = products.filter((_, i) => isVisible(i))
_52
_52
if (visibleProducts.length > 0) {
_52
viewItemList({
_52
item_list_name: listName,
_52
items: visibleProducts.map((p, index) => ({
_52
item_id: p.id,
_52
item_name: p.name,
_52
index: sliderState.currentItem + index,
_52
price: p.price
_52
}))
_52
})
_52
}
_52
}, [sliderState.currentItem, products, listName])
_52
_52
return (
_52
<div {...handlers} className="carousel">
_52
<button onClick={() => slide('previous')} aria-label="Previous products">
_52
_52
</button>
_52
_52
<div className="carousel-track">
_52
{products.map((product, i) => (
_52
<ProductCard
_52
key={product.id}
_52
product={product}
_52
visible={isVisible(i)}
_52
/>
_52
))}
_52
</div>
_52
_52
<button onClick={() => slide('next')} aria-label="Next products">
_52
_52
</button>
_52
</div>
_52
)
_52
}

Building a shipping calculator

This example builds a shipping calculator that allows shoppers estimate delivery costs and times based on their postal code. It combines two hooks:
  • useShippingSimulation_unstable: Runs the shipping simulation client-side and returns available delivery options.
  • useFormattedPrice_unstable: Formats prices according to the store's current locale and currency.

_51
import { useState } from 'react'
_51
import { useShippingSimulation_unstable as useShippingSimulation } from '@faststore/core/experimental'
_51
import { useFormattedPrice_unstable as useFormattedPrice } from '@faststore/core/experimental'
_51
_51
function ShippingCalculator({ items }) {
_51
const [postalCode, setPostalCode] = useState('')
_51
const { simulate, data, loading, error } = useShippingSimulation()
_51
const formatPrice = useFormattedPrice
_51
_51
const handleCalculate = () => {
_51
if (postalCode.length >= 5) {
_51
simulate({
_51
postalCode,
_51
items: items.map(item => ({
_51
id: item.id,
_51
quantity: item.quantity,
_51
seller: item.seller
_51
}))
_51
})
_51
}
_51
}
_51
_51
return (
_51
<div className="shipping-calculator">
_51
<input
_51
type="text"
_51
value={postalCode}
_51
onChange={(e) => setPostalCode(e.target.value)}
_51
placeholder="Enter postal code"
_51
maxLength={9}
_51
/>
_51
<button onClick={handleCalculate} disabled={loading}>
_51
{loading ? 'Calculating...' : 'Calculate Shipping'}
_51
</button>
_51
_51
{error && <p className="error">Unable to calculate shipping</p>}
_51
_51
{data?.logisticsInfo && (
_51
<div className="shipping-options">
_51
{data.logisticsInfo[0].slas.map(sla => (
_51
<div key={sla.id} className="shipping-option">
_51
<span>{sla.name}</span>
_51
<span>{formatPrice(sla.price)}</span>
_51
<span>{sla.shippingEstimate}</span>
_51
</div>
_51
))}
_51
</div>
_51
)}
_51
</div>
_51
)
_51
}

Contributors
2
Photo of the contributor
Photo of the contributor
Was this helpful?
Yes
No
Suggest Edits (GitHub)
Contributors
2
Photo of the contributor
Photo of the contributor
Was this helpful?
Suggest edits (GitHub)
On this page