{"id":19312106,"url":"https://github.com/bigcommerce/storefront-data-hooks","last_synced_at":"2025-04-05T22:04:19.074Z","repository":{"id":39747140,"uuid":"306715394","full_name":"bigcommerce/storefront-data-hooks","owner":"bigcommerce","description":"Hooks for React Storefront UI Components","archived":false,"fork":false,"pushed_at":"2023-05-08T20:21:57.000Z","size":700,"stargazers_count":166,"open_issues_count":12,"forks_count":35,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-03-29T21:02:58.902Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bigcommerce.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-23T18:22:21.000Z","updated_at":"2025-01-28T20:59:58.000Z","dependencies_parsed_at":"2024-06-18T18:28:41.641Z","dependency_job_id":"ffccf30f-5150-4efd-a285-d9e274a6a288","html_url":"https://github.com/bigcommerce/storefront-data-hooks","commit_stats":{"total_commits":173,"total_committers":16,"mean_commits":10.8125,"dds":"0.34682080924855496","last_synced_commit":"7076ceda46d4710c9eed99d8142d80b4d4393f95"},"previous_names":["bigcommerce-labs/storefront-data-hooks"],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigcommerce%2Fstorefront-data-hooks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigcommerce%2Fstorefront-data-hooks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigcommerce%2Fstorefront-data-hooks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigcommerce%2Fstorefront-data-hooks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bigcommerce","download_url":"https://codeload.github.com/bigcommerce/storefront-data-hooks/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247406085,"owners_count":20933803,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T00:32:52.946Z","updated_at":"2025-04-05T22:04:19.044Z","avatar_url":"https://github.com/bigcommerce.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Last version](https://img.shields.io/github/tag/bigcommerce/storefront-data-hooks.svg?style=flat-square)\n[![NPM Status](https://img.shields.io/npm/dm/@bigcommerce/storefront-data-hooks.svg?style=flat-square)](https://www.npmjs.org/package/@bigcommerce/storefront-data-hooks)\n\nTable of Contents\n=================\n\n   * [BigCommerce Storefront Data Hooks](#bigcommerce-storefront-data-hooks)\n      * [Installation](#installation)\n      * [General Usage](#general-usage)\n         * [CommerceProvider](#commerceprovider)\n         * [useLogin hook](#uselogin-hook)\n         * [useLogout](#uselogout)\n         * [useCustomer](#usecustomer)\n         * [useSignup](#usesignup)\n         * [usePrice](#useprice)\n      * [Cart Hooks](#cart-hooks)\n         * [useCart](#usecart)\n         * [useAddItem](#useadditem)\n         * [useUpdateItem](#useupdateitem)\n         * [useRemoveItem](#useremoveitem)\n      * [Wishlist Hooks](#wishlist-hooks)\n      * [Product Hooks and API](#product-hooks-and-api)\n         * [useSearch](#usesearch)\n         * [getAllProducts](#getallproducts)\n         * [getProduct](#getproduct)\n      * [Customer Addresses Hooks](#customer-addresses-hooks)\n         * [useAddresses](#useaddresses)\n         * [useAddAddress](#useaddaddress)\n         * [useUpdateAddress](#useupdateaddress)\n         * [useRemoveAddress](#useremoveaddress)\n      * [Checkout](#checkout)\n      * [Troubleshooting](#troubleshooting)\n      * [More](#more)\n\n# BigCommerce Storefront Data Hooks\n\n\u003e This project is under active development, new features and updates will be continuously added over time\n\nUI hooks and data fetching methods built from the ground up for e-commerce applications written in React, that use BigCommerce as a headless e-commerce platform. The package provides:\n\n- Code splitted hooks for data fetching using [SWR](https://swr.vercel.app/), and to handle common user actions\n- Code splitted data fetching methods for initial data population and static generation of content\n- Helpers to create the API endpoints that connect to the hooks, very well suited for Next.js applications\n\n## Installation\n\nTo install:\n\n```\nyarn add @bigcommerce/storefront-data-hooks\n```\n\nAfter install, the first thing you do is: \u003cb\u003eset your environment variables\u003c/b\u003e in `.env.local`\n\n```sh\nBIGCOMMERCE_CHANNEL_ID=\nBIGCOMMERCE_STOREFRONT_API_TOKEN=\nBIGCOMMERCE_STOREFRONT_API_URL=\nBIGCOMMERCE_STORE_API_CLIENT_ID=\nBIGCOMMERCE_STORE_API_TOKEN=\nBIGCOMMERCE_STORE_API_URL=\nBIGCOMMERCE_STORE_HASH=\nSECRET_COOKIE_PASSWORD=\n```\n\n## General Usage\n\n### CommerceProvider\n\nThis component is a provider pattern component that creates commerce context for it's children. It takes config values for the locale and an optional `fetcherRef` object for data fetching.\n\n```jsx\n...\nimport { CommerceProvider } from '@bigcommerce/storefront-data-hooks'\n\nconst App = ({ locale = 'en-US', children }) =\u003e {\n  return (\n    \u003cCommerceProvider locale={locale}\u003e\n      {children}\n    \u003c/CommerceProvider\u003e\n  )\n}\n...\n```\n\n### useLogin hook\n\nHook for bigcommerce user login functionality, returns `login` function to handle user login.\n\n```jsx\n...\nimport useLogin from '@bigcommerce/storefront-data-hooks/use-login'\n\nconst LoginView = () =\u003e {\n  const login = useLogin()\n\n  const handleLogin = async () =\u003e {\n    await login({\n      email,\n      password,\n    })\n  }\n\n  return (\n    \u003cform onSubmit={handleLogin}\u003e\n      {children}\n    \u003c/form\u003e\n  )\n}\n...\n```\n\n#### Login SSO\n\nTo authenticate a user using the Customer Login API, it's necessary to point the `useLogin` hook to your own authentication endpoint.\n\n```jsx\nconst login = useLogin({\n  options: {\n    url: '/api/your-own-authentication'\n  },\n})\n```\n\nThat authentication endpoint have to return a `Set-Cookie` header with `SHOP_TOKEN=your_customer_authentication_token`. [See an example.](https://gist.github.com/jorgemasta/c709b63501344970026f3a3e7646cc77)\n\n### useLogout\n\nHook to logout user.\n\n```jsx\n...\nimport useLogout from '@bigcommerce/storefront-data-hooks/use-logout'\n\nconst LogoutLink = () =\u003e {\n  const logout = useLogout()\n  return (\n    \u003ca onClick={() =\u003e logout()}\u003e\n      Logout\n    \u003c/a\u003e\n  )\n}\n```\n\n### useCustomer\n\nHook for getting logged in customer data, and fetching customer info.\n\n```jsx\n...\nimport useCustomer from '@bigcommerce/storefront-data-hooks/use-customer'\n...\n\nconst Profile = () =\u003e {\n  const { data } = useCustomer()\n\n  if (!data) {\n    return null\n  }\n\n  return (\n    \u003cdiv\u003eHello, {data.firstName}\u003c/div\u003e\n  )\n}\n```\n\n### useSignup\n\nHook for bigcommerce user signup, returns `signup` function to handle user signups.\n\n```jsx\n...\nimport useSignup from '@bigcommerce/storefront-data-hooks/use-signup'\n\nconst SignupView = () =\u003e {\n  const signup = useSignup()\n\n  const handleSignup = async () =\u003e {\n    await signup({\n      email,\n      firstName,\n      lastName,\n      password,\n    })\n  }\n\n  return (\n    \u003cform onSubmit={handleSignup}\u003e\n      {children}\n    \u003c/form\u003e\n  )\n}\n...\n```\n\n### usePrice\n\nHelper hook to format price according to commerce locale, and return discount if available.\n\n```jsx\nimport usePrice from '@bigcommerce/storefront-data-hooks/use-price'\n...\n  const { price, discount, basePrice } = usePrice(\n    data \u0026\u0026 {\n      amount: data.cart_amount,\n      currencyCode: data.currency.code,\n    }\n  )\n...\n```\n\n## Cart Hooks\n\n### useCart\n\nReturns the current cart data for use\n\n```jsx\n...\nimport useCart from '@bigcommerce/storefront-data-hooks/cart/use-cart'\n\nconst countItem = (count: number, item: any) =\u003e count + item.quantity\nconst countItems = (count: number, items: any[]) =\u003e\n  items.reduce(countItem, count)\n\nconst CartNumber = () =\u003e {\n  const { data } = useCart()\n  const itemsCount = Object.values(data?.line_items ?? {}).reduce(countItems, 0)\n\n  return itemsCount \u003e 0 ? \u003cspan\u003e{itemsCount}\u003c/span\u003e : null\n}\n```\n\n### useAddItem\n\n```jsx\n...\nimport useAddItem from '@bigcommerce/storefront-data-hooks/cart/use-add-item'\n\nconst AddToCartButton = ({ productId, variantId }) =\u003e {\n  const addItem = useAddItem()\n\n  const addToCart = async () =\u003e {\n    await addItem({\n      productId,\n      variantId,\n    })\n  }\n\n  return \u003cbutton onClick={addToCart}\u003eAdd To Cart\u003c/button\u003e\n}\n...\n```\n\n### useUpdateItem\n\n```jsx\n...\nimport useUpdateItem from '@bigcommerce/storefront-data-hooks/cart/use-update-item'\n\nconst CartItem = ({ item }) =\u003e {\n  const [quantity, setQuantity] = useState(item.quantity)\n  const updateItem = useUpdateItem(item)\n\n  const updateQuantity = async (e) =\u003e {\n    const val = e.target.value\n    await updateItem({ quantity: val })\n  }\n\n  return (\n    \u003cinput\n      type=\"number\"\n      max={99}\n      min={0}\n      value={quantity}\n      onChange={updateQuantity}\n    /\u003e\n  )\n}\n...\n```\n\n### useRemoveItem\n\nProvided with a cartItemId, will remove an item from the cart:\n\n```jsx\n...\nimport useRemoveItem from '@bigcommerce/storefront-data-hooks/cart/use-remove-item'\n\nconst RemoveButton = ({ item }) =\u003e {\n  const removeItem = useRemoveItem()\n\n  const handleRemove = async () =\u003e {\n    await removeItem({ id: item.id })\n  }\n\n  return \u003cbutton onClick={handleRemove}\u003eRemove\u003c/button\u003e\n}\n...\n```\n\n## Wishlist Hooks\n\nWishlist hooks are similar to cart hooks. See the below example for how to use `useWishlist`, `useAddItem`, and `useRemoveItem`.\n\n```jsx\nimport useAddItem from '@bigcommerce/storefront-data-hooks/wishlist/use-add-item'\nimport useRemoveItem from '@bigcommerce/storefront-data-hooks/wishlist/use-remove-item'\nimport useWishlist from '@bigcommerce/storefront-data-hooks/wishlist/use-wishlist'\n\nconst WishlistButton = ({ productId, variant }) =\u003e {\n  const addItem = useAddItem()\n  const removeItem = useRemoveItem()\n  const { data } = useWishlist()\n  const { data: customer } = useCustomer()\n  const itemInWishlist = data?.items?.find(\n    (item) =\u003e\n      item.product_id === productId \u0026\u0026\n      item.variant_id === variant?.node.entityId\n  )\n\n  const handleWishlistChange = async (e) =\u003e {\n    e.preventDefault()\n\n    if (!customer) {\n      return\n    }\n\n    if (itemInWishlist) {\n      await removeItem({ id: itemInWishlist.id! })\n    } else {\n      await addItem({\n        productId,\n        variantId: variant?.node.entityId!,\n      })\n    }\n  }\n\n  return (\n    \u003cbutton onClick={handleWishlistChange}\u003e\n      \u003cHeart fill={itemInWishlist ? 'var(--pink)' : 'none'} /\u003e\n    \u003c/button\u003e\n  )\n}\n```\n\n## Product Hooks and API\n\n### useSearch\n\n`useSearch` handles searching the bigcommerce storefront product catalog by catalog, brand, and query string. It also allows pagination.\n\n```jsx\n...\nimport useSearch from '@bigcommerce/storefront-data-hooks/products/use-search'\n\nconst SearchPage = ({ searchString, category, brand, sortStr }) =\u003e {\n  const { data } = useSearch({\n    search: searchString || '',\n    categoryId: category?.entityId,\n    brandId: brand?.entityId,\n    sort: sortStr || '',\n    page: 1\n  })\n\n  const { products, pagination } = data\n\n  return (\n    \u003cGrid layout=\"normal\"\u003e\n      {products.map(({ node }) =\u003e (\n        \u003cProductCard key={node.path} product={node} /\u003e\n      ))}\n      \u003cPagination {...pagination}\u003e\n    \u003c/Grid\u003e\n  )\n}\n```\n\n### getAllProducts\n\nAPI function to retrieve a product list.\n\n```js\nimport { getConfig } from '@bigcommerce/storefront-data-hooks/api'\nimport getAllProducts from '@bigcommerce/storefront-data-hooks/api/operations/get-all-products'\n\nconst { products } = await getAllProducts({\n  variables: { field: 'featuredProducts', first: 6 },\n  config,\n  preview,\n})\n```\n\n### getProduct\n\nAPI product to retrieve a single product when provided with the product\nslug string.\n\n```js\nimport { getConfig } from '@bigcommerce/storefront-data-hooks/api'\nimport getProduct from '@bigcommerce/storefront-data-hooks/api/operations/get-product'\n\nconst { product } = await getProduct({\n  variables: { slug },\n  config,\n  preview,\n})\n```\n\n## Customer Addresses Hooks\n### useAddresses\n\nHook for returning the current users addresses\n\n```javascript\nimport useAddresses from '@bigcommerce/storefront-data-hooks/address/use-addresses'\n\nconst AddressPage = () =\u003e {\n  const { data } = useAddresses()\n\n  return (\n    \u003cdiv\u003e\n      \u003cpre\u003e{JSON.stringify(data?.addresses, null, 2)}\u003c/pre\u003e\n    \u003c/div\u003e\n  )\n}\n\n```\n\n### useAddAddress\n\nHook for adding customer address\n\n```javascript\nimport useAddAddress from '@bigcommerce/storefront-data-hooks/address/use-add-address'\n\nconst AddressPage = () =\u003e {\n  const addAddress = useAddAddress()\n\n  const handleAddAddress = async () =\u003e {\n    await addAddress({\n      first_name: \"Rod\",\n      last_name: \"Hull\",\n      address1: \"Waffle Road\",\n      city: \"Bristol\",\n      state_or_province: \"Bristol\",\n      postal_code: \"WAF FLE\",\n      country_code: \"GB\",\n      phone: \"01234567890\",\n      address_type: \"residential\",\n    })\n  }\n\n  return (\n    \u003cform onSubmit={handleAddAddress}\u003e\n      {children}\n    \u003c/form\u003e\n  )\n}\n\n```\n\n### useUpdateAddress\n\nHook for updating a customer address\n\n```javascript\nimport useUpdateAddress from '@bigcommerce/storefront-data-hooks/address/use-update-address'\n\nconst AddressPage = () =\u003e {\n  const updateAddress = useUpdateAddress()\n\n  const handleUpdateAddress = async () =\u003e {\n    await updateAddress({\n      id: 4,\n      first_name: \"Rod\",\n      last_name: \"Hull\",\n      address1: \"Waffle Road\",\n      city: \"Bristol\",\n      state_or_province: \"Bristol\",\n      postal_code: \"WAF FLE\",\n      country_code: \"GB\",\n      phone: \"01234567890\",\n      address_type: \"residential\",\n      id: 12\n    })\n  }\n\n  return (\n    \u003cform onSubmit={handleUpdateAddress}\u003e\n      {children}\n    \u003c/form\u003e\n  )\n}\n\n```\n\n### useRemoveAddress\n\nHook for removing a customers address\n\n```javascript\nimport useRemoveAddress from '@bigcommerce/storefront-data-hooks/address/use-remove-address'\n\nconst AddressPage = () =\u003e {\n  const removeAddress = useRemoveAddress()\n\n  const handleUpdateAddress = async () =\u003e {\n    await removeAddress({\n      id: 4,\n    })\n  }\n\n  return (\n    \u003cform onSubmit={handleUpdateAddress}\u003e\n      {children}\n    \u003c/form\u003e\n  )\n}\n\n```\n\n\n## Checkout\n\n\u003e The checkout only works on **production** and with a custom domain\n\nThe recommended method is the [Embedded Checkout](https://developer.bigcommerce.com/api-docs/storefronts/embedded-checkout/embedded-checkout-tutorial), follow the tutorial to create a channel and a site. Notes:\n\n- The channel should be of type `storefront`\n- The site url must be your production url (e.g: https://mystorefront.com)\n- This package takes care of the cart and redirect links creation\n- Your bigcommerce storefront must be a subdomain of your headless storefront (eg: https://bc.mystorefront.com)\n\n![example image](https://cdn-std.droplr.net/files/acc_896732/CSo83V)\n\n## Troubleshooting\n\u003cdetails\u003e\n  \u003csummary\u003eWhen I try to create a customer with \u003ccode\u003euseSignup\u003c/code\u003e, I receive an error but the user is created\u003c/summary\u003e\n\n  The `useSignup` hooks tries to login the user after creating it. Probably you have an error with the login. Checkout that your have your store **Open** since if the store is *Down for Maintenance* the users can't login.\n  ![image](https://user-images.githubusercontent.com/4943868/102613733-f46abd80-412a-11eb-8438-744be2351512.png)\n\n  Thanks @Strapazzon 🚀\n\u003c/details\u003e\n\n## Contributing\n\n### Configuration\n\nYou will need to crate a `.env` file from the `.env.example` with the following keys.\n- BIGCOMMERCE_STOREFRONT_API_TOKEN\n- BIGCOMMERCE_STOREFRONT_API_URL\n\nThe token and url will be crated in your BC Store admin section: Advanced Settings -\u003e API Accounts.\nOnce you have added the `.env` configuration, run:\n\n- `yarn generate` to generate your new schema.\n- `yarn build` to build a new set of compiled files.\n\nLink the package locally to your app with `yarn link` or by using the [YALC](https://www.npmjs.com/package/yalc) tool.\n\n### Pull Requests\n\nPull requests, issues and comments are welcome! See [Contributing](CONTRIBUTING.md) for more details.\n\nMany thanks to all [contributors](https://github.com/bigcommerce/storefront-data-hooks/contributors)!\n## More\n\nFeel free to read through the source for more usage, and check the commerce vercel demo and commerce repo for usage examples: ([demo.vercel.store](https://demo.vercel.store/)) ([repo](https://github.com/vercel/commerce))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigcommerce%2Fstorefront-data-hooks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbigcommerce%2Fstorefront-data-hooks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigcommerce%2Fstorefront-data-hooks/lists"}