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:
| Area | How hooks help |
|---|---|
| Faster development | Pre-built functionality reduces implementation time and removes the need for repetitive setup code. |
| Consistency | Standardized patterns across your store keep the codebase predictable and easier to maintain. |
| Maintainability | Updates to core hooks automatically benefit your custom components, reducing manual upkeep. |
| Accessibility | Built-in accessibility features (focus management, ARIA support) help ensure compliance with WCAG standards. |
| Analytics integration | Seamless GA4 event tracking is available without manual instrumentation. |
| Type safety | Full TypeScript support with type definitions for safer customization. |
| Component overrides | Hooks let you override native components while preserving core functionality. |
| Custom sections | Build new CMS sections with full access to store data and features. |
| Extended behavior | Add custom logic on top of existing features without breaking core functionality. |
| State management | Access global store state without needing additional state-management libraries. |
Available hooks
FastStore hooks are organized into the following categories:
| Hook categories | Description |
|---|---|
| UI and interaction hooks | Available from the @faststore/components package. These hooks manage user interface state and interactions. |
| Analytics hooks | Available from the @faststore/core package. These hooks enable tracking and analytics integration. |
| Experimental hooks | Available 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
| Hook | Description | Use cases |
|---|---|---|
UIProvider | Context 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. |
useUI | Access global UI state and actions managed by UIProvider. | Control the cart sidebar, modals, navigation menu, filters, toasts, popovers, and region selection from any component. |
useSearch | Manages search interface state within the SearchProvider context. | Building custom search components, managing search input state, implementing search suggestions. |
useSlider | Manages carousel/slider state including the current page, navigation, and swipe gestures. | Creating product carousels, image galleries, testimonial sliders, or any multi-item navigation component. |
useSlideVisibility | Determines visibility state for slider items based on the current index. | Lazy-loading carousel images, applying visibility-based animations, optimizing render performance. |
useOnClickOutside | Detects clicks outside a referenced element and triggers a callback. | Closing modals when clicking backdrop, dismissing dropdowns, hiding popovers on outside interaction. |
useTrapFocus | Traps keyboard focus within a container element for accessibility. | Modal dialogs, slide-out panels, any overlay that should constrain focus for keyboard navigation. |
useScrollDirection | Detects scroll direction (up/down) for responsive header behavior. | Hide/show sticky headers on scroll, trigger animations based on scroll direction, optimize mobile screen space. |
useFadeEffect | Creates a progressive fade-in effect based on scroll position or distance. | Subtle entrance animations, progressive content reveal, enhancing visual hierarchy. |
useSKUMatrix | Manages SKU/variant selection logic within the SKUMatrixProvider context. | Building custom variant selectors, product configuration interfaces, size/color pickers. |
useProductComparison | Manages product comparison list within the ProductComparisonProvider. | Product comparison features, "Compare" buttons on product cards, comparison page implementation. |
Analytics hooks
| Hook | Description | Use cases |
|---|---|---|
usePageViewEvent | Sends GA4 page view events automatically on route changes. | Track page navigation, monitor user journey, required for GA4 analytics dashboards. |
useViewItemListEvent | Sends 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_unstableand may change in future releases. Always test them thoroughly before deploying to production.
Authentication
| Hook | Description | Use cases |
|---|---|---|
useAuth_unstable | Manages user authentication state and actions. | Login/logout functionality, protected routes, personalized content. |
Cart
| Hook | Description | Use cases |
|---|---|---|
cartStore_unstable | Store instance for cart state management (not a hook, but a store object). | Direct cart state manipulation, accessing cart data outside React components. |
useCart_unstable | Access current cart state reactively. | Display cart summary, show item count, calculate totals in any component. |
useBuyButton_unstable | Provides buy button functionality with cart integration and analytics. | Creating custom "Add to Cart" buttons with automatic analytics tracking and cart sidebar integration. |
useCartToggleButton_unstable | Toggles cart sidebar visibility. | Cart icon buttons, mini-cart toggles in header/navigation. |
useCheckoutButton_unstable | Provides checkout button functionality with validation and navigation. | Cart page checkout buttons, mini-cart proceed to checkout, custom checkout flows. |
useRemoveButton_unstable | Removes items from cart with analytics tracking. | Cart item removal, mini-cart management, order review pages. |
Delivery promise
| Hook | Description | Use cases |
|---|---|---|
deliveryPromiseStore_unstable | Store for delivery promise data including pickup points and delivery options. | Accessing delivery data across components without prop drilling. |
useDeliveryPromise_unstable | Access and manage delivery promise state, pickup points, and delivery options. | Shipping calculators, delivery date displays, pickup point selectors, store locators. |
GraphQL
| Hook | Description | Use cases |
|---|---|---|
useQuery_unstable | Execute GraphQL queries with automatic caching and error handling. | Fetching product data, custom data requirements, extending FastStore API. |
useLazyQuery_unstable | Execute GraphQL queries on-demand (ex.: when a button is clicked). | Search suggestions on input, load-more pagination, conditional data fetching. |
Newsletter
| Hook | Description | Use cases |
|---|---|---|
useNewsletter_unstable | Newsletter subscription functionality. | Newsletter signup forms, email capture modals, footer subscription widgets. |
Product
| Hook | Description | Use cases |
|---|---|---|
useDiscountPercent_unstable | Calculate discount percentage from the price and list price. | Display discount badges, savings indicators, promotional information. |
useFormattedPrice_unstable | Format price values according to the current locale and currency. | Display prices consistently across the store with proper currency symbols and formatting. |
useLocalizedVariables_unstable | Provides localized variables for queries based on the current session. | Multi-locale stores, currency conversion, region-specific content. |
useProductQuery_unstable | Fetch detailed product data by ID or slug. | Product detail pages, quick view modals, product preview cards. |
useProductLink_unstable | Generate SEO-friendly product URLs. | Product card links, navigation to Product Detail Pages (PDPs), breadcrumbs. |
useProductsPrefetch_unstable | Preload product data for faster navigation. | Hover intent on product cards, carousel pre-loading, performance optimization. |
useProductGalleryQuery_unstable | Fetch product gallery images with optimization. | Product image galleries, zoom functionality, image carousels. |
useGalleryPage_unstable | Manage gallery pagination and navigation. | Product image galleries, media viewers, image sliders. |
useCreateUseGalleryPage_unstable | Create custom gallery page hooks with specific configurations. | Advanced gallery implementations, custom pagination logic. |
Search
| Hook | Description | Use cases |
|---|---|---|
useFilter_unstable | Manage search filters and facets. | Product listing filters, search result refinement, faceted navigation. |
useDelayedFacets_unstable | Debounce facet updates to improve performance. | High-traffic PLPs, complex filter combinations, performance optimization. |
useDelayedPagination_unstable | Debounce pagination to improve performance. | Large product catalogs, infinite scroll implementations, performance-critical pages. |
useSearchHistory_unstable | Access user's recent search queries. | Search autocomplete, recent searches display, search suggestions. |
useSuggestions_unstable | Provide search term suggestions. | Autocomplete dropdowns, search as you type, query assistance. |
useTopSearch_unstable | Retrieve popular search terms. | Trending searches, search landing page, discovery features. |
Session
| Hook | Description | Use cases |
|---|---|---|
sessionStore_unstable | Store instance for session data (locale, currency, user info). | Direct session manipulation, accessing session data outside React components. |
useSession_unstable | Access current session data reactively. | Personalized content, currency display, shipping calculations, user-specific features. |
validateSession_unstable | Validate and refresh session data. | Session management, token refresh flows, authentication state sync. |
Shipping
| Hook | Description | Use cases |
|---|---|---|
getShippingSimulation_unstable | Get shipping simulation data (function, not a hook). | Server-side shipping calculations, initial page load data, static generation. |
useShippingSimulation_unstable | Run shipping simulations client-side. | Shipping calculators, delivery estimate displays, cart shipping options, postal code input. |
UI
| Hook | Description | Use cases |
|---|---|---|
useScreenResize_unstable | Detect 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/componentshooks for interface interactions. - Business logic: Use
@faststore/core/experimentalhooks 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 aspushToast, 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.
_30import { useBuyButton_unstable as useBuyButton } from '@faststore/core/experimental'_30import { useUI } from '@faststore/components'_30_30function 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 thecloseModalaction.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.
_36import { useRef, useState } from 'react'_36import { useOnClickOutside, useTrapFocus, useUI } from '@faststore/components'_36import { useSuggestions_unstable as useSuggestions } from '@faststore/core/experimental'_36_36function 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}
Implementing a product carousel with analytics
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.
_52import { useSlider, useSlideVisibility } from '@faststore/components'_52import { useViewItemListEvent } from '@faststore/core'_52import { useEffect } from 'react'_52_52function 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.
_51import { useState } from 'react'_51import { useShippingSimulation_unstable as useShippingSimulation } from '@faststore/core/experimental'_51import { useFormattedPrice_unstable as useFormattedPrice } from '@faststore/core/experimental'_51_51function 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}