BigCommerce

Frontend Checkout

useCartState

The useCartState hook can be used to get the current state of the user's cart.

🚧

The data returned by useCartState is different than the CMS data.

import { useCartState } from 'frontend-checkout' 

const cart = useCartState()

// Cart
{
  id: string // ID of current cart.
  items: Items[] // Array of items currently in cart. Check `Items` type below.
  // 🚨 `inventory` is to be deprecated 🚨
 // Use https://docs.getshogun.com/shogun-frontend-guides/docs/frontend-checkout-migrate-to-inventory-actions
  inventory: {
   products: Record<productId, {
     availableForSale: boolean  // Indicates should you allow purchasing of a product, e.g. out of stock.
     quantity: number // The available quantity of a given product, if allowed on store.
     minOrder?: number // Minimum order constraint, adjustable in Shogun CMS - Product Content Group.
     maxOrder?: number // Maximum order constraint.
   }
   productVariants: Record<variantId, {
     availableForSale: boolean
     quantity: number
     minOrder?: number
     maxOrder?: number
   }
   status: 'loading' | 'loaded' | 'error' // Status of loading products from CMS
  }
  subtotalPrice: number // Total price of all items in cart, before shipping, taxes, and discounts.
  currencyCode: string // Cart currency code, e.g. "USD".
  isCartShown: boolean // Flag for managing should cart modal or drawer be visible.
  checkoutUrl: string // Url to redirect users when they press `Checkout` link/button.
  totalPrice?: number //Total price of all items in cart after taxes, doesn't include discounts.
  discountAmount?: number //Discounted amount
  taxTotal?: number
  coupons?: {
    id: string
    code: string
    displayName: string
    couponType: number
    discountedAmount: number
  }[]
  giftCertificates?: {
    balance: number
    code: string
    purchaseDate: string
    remaining: number
    used: number
  }[]
  consignment?: {
    id: string
    shippingAddress: {
      id: string
      firstName: string
      lastName: string
      email: string
      company: string
      address1: string
      address2: string
      city: string
      state: string
      stateCode: string
      countryCode: string
      postalCode: string
      phone: string
      customFields: {
        id: string
        value: string
      }[]
    }
    availableShippingOptions: BigCommerceShippingOption[]
    selectedShippingOption: BigCommerceShippingOption | null
    couponDiscounts: {
      code: string
      amount: number
    }[]
    discounts: {
      id: number
    }[]
    shippingCostIncTax: number
    shippingCostExTax: number
    handlingCostIncTax: number
    handlingCostExTax: number
    lineItemIds: string[]
  }
}

Items type

interface BigCommerceAPILineItemOption {
  name_id: number
  value_id: number
}

interface BigCommerceAPILineItem {
  id: string
  product_id: number
  variant_id: number
  quantity: number
  name: string
  sku: string
  list_price: number
  image_url: string
  url: string
  coupon_amount: number
  discount_amount: number
  discounts: {
    id: string
    discounted_amount: number
  }[]
  extended_list_price: number
  extended_sale_price: number
  is_mutable: boolean
  is_require_shipping: boolean
  parent_id: number | null
  sale_price: number
  taxable: boolean
  options: BigCommerceAPILineItemOption[]
}

useCartActions

The useCartActions hook can be used to get actions available for manipulating the cart.

import { useCartActions } from 'frontend-checkout'

addItems

📘

Note that optionSelections is required if a product has options.

/**
 * Add items to cart.
 * addItems: (items: Item | Item[]) => Promise<Cart>
 */
const { addItems } = useCartActions()

/**
 * Item: {
 *  id: number
 *  quantity: number
 *  [key: string]?: any
 * }
 */
const item = {
  // product id, in Shogun Frontend CMS that is `product.id`
  id: 124810,
  quantity: 1,
  // optionSelections required if a product has options
  optionSelections: [{ optionId: 12, optionValue: 120 }],
}

// To add a single item to the cart:
await addItems(item)

// To add multiple items to the cart:
await addItems([item, anotherItem])

updateItems

/**
 * Update items in cart.
 * updateItems: (items: Item | Item[]) => Promise<Cart>
 */
const { updateItems } = useCartActions()

const { items } = useCartState()

/**
 * Item: {
 *  id: string | number
 *  quantity: number
 *  [key: string]?: any
 * }
 */
const item = {
  // id of the item in the cart that you want to update
  id: items[0].id,
  // lineItemId of the item in the cart you want to update
  lineItemId: items[0].lineItemId,
  // change the quantity
  quantity: 2,
  // optionSelections required if a product has options
  optionSelections: items[0].optionSelections,
}

// To update a single item in the cart:
await updateItems(item)

// To update multiple items in the cart:
await updateItems([item, anotherItem])

removeItems

/**
 * Remove items from cart.
 * removeItems: (itemIds: string | string[]) => Promise<Cart>
 */
const { removeItems } = useCartActions()

const { items } = useCartState()

const itemId = items[0].lineItemId // remove first item in cart

// To remove a single item from the cart:
await removeItems(itemId)

// To remove multiple items from the cart:
await removeItems([itemid, anotherItemId])

isProductInInventory

❗️

TO BE DEPRECATED

Use isProductAvailableForSale instead.

/**
 * Check if product is in the inventory.
 * isProductInInventory: ({ id: ItemId, type: ProductType = 'Product' }) => boolean
 */
const { isProductInInventory } = useCartActions()

// storefrontId
isProductInInventory({ id: 124810 })

isProductAvailableForSale

/**
 * Check if product is available for sale from the inventory.
 * isProductAvailableForSale: ({ id: ItemId, type: ProductType = 'Product' }) => boolean
 */
const { isProductAvailableForSale } = useCartActions()

// storefrontId
isProductAvailableForSale({ id: 124810 })

getProductQuantity

/**
 * Get product quantity from the inventory.
 * getProductQuantity: ({ id: ItemId, type: ProductType = 'Product' }) => number
 */
const { getProductQuantity } = useCartActions()

// storefrontId
getProductQuantity({ id: 124810 })

getProductMinOrder

/**
 * Get product minimum order from the inventory.
 * getProductMinOrder: ({ id: ItemId, type: ProductType = 'Product' }) => number | undefined
 */
const { getProductMinOrder } = useCartActions()

// storefrontId
getProductMinOrder({ id: 124810 })

getProductMaxOrder

/**
 * Get product maximum order from the inventory.
 * getProductMaxOrder: ({ id: ItemId, type: ProductType = 'Product' }) => number | undefined
 */
const { getProductMaxOrder } = useCartActions()

// storefrontId
getProductMaxOrder({ id: 124810 })

getProductPrice

/**
 * Get product price.
 * getProductPrice: ({ id: string | number }) => string | number | undefined
 */
const { getProductPrice } = useCartActions()

// storefrontId
await getProductPrice({ id: 124810 })

getShippingQuotes

/**
 * Get shipping quotes for provided address.
 * getShippingQuotes: (shippingAddress: ShippingAddress) => BigCommerceShippingOption[]
 * 
 * type ShippingAddress = {
 *   city: string
 *   state: string
 *   stateCode?: string
 *   countryCode: string
 *   postalCode: string
 *   firstName?: string
 *   lastName?: string
 *   email?: string
 *   phone?: string
 *   address1?: string
 * }
 * 
 * type BigCommerceShippingOption = {
 *  id: string
 *  type: string
 *  description: string
 *  imageUrl: string
 *  cost: number
 *  transitTime: string
 *  additionalDescription: string
 * }
 */

const { getShippingQuotes } = useCartActions()

const shippingOptions = await getShippingQuotes({
  city: 'New York',
  countryCode: 'US',
  postalCode: '10001',
  state: 'New York',
})

showCart

/**
 * Show cart.
 * showCart: () => void
 */
const { showCart } = useCartActions()

showCart() // isCartShown from useCartState will become true.

hideCart

/**
 * Hide cart.
 * hideCart: () => void
 */
const { hideCart } = useCartActions()

hideCart() // isCartShown from useCartState will become false.

useInventory

The useInventory hook can be used to retrieve inventory data on demand.

/**
 * Retrieve inventory data directly from the platform API
 * This hook accepts an array of IDs
 * The hook will retrieve the inventory data on the given product IDs
 * Optionally, an interval (in milliseconds)  can be passed to automatically refresh the data after the given interval
 * useInventory: (props: { ids: string[] | number[], inverval?: number, productType?: 'Product' | 'ProductVariant' }) => {
 *   products: Record<id, { availableForSale: boolean, quantity: number, minOrder: number, maxOrder: number, price: number }>
 *   status: 'initial' | 'loading' | 'loaded' | 'error'
 * }
 */
import { useInventory } from 'frontend-checkout'

const id = 124810

// By passing an id and product type, useInventory will fetch the data for given ids
// Note that ids will always expect an array of IDs whether you wish to retrieve the data
// For a single product or multiple products.

// To retrieve data for a single product, pass the ID as a single element array
const { products, status } = useInventory({ ids: [id], productType: 'Product' })

// By passing an id and product type, useInventory will fetch the data for given ids
const { products, status } = useInventory({ ids: [id], productType: 'Product' })
// minOrder and maxOrder comes from Shogun Frontend CMS and
// it will only be updated after building and publishing the store
const { availableForSale, quantity, minOrder, maxOrder, price } = products[id] || {}

// To retrieve the inventory data for multiple products, pass the IDs as an array
// Note that in this case you must ensure that all IDs are of the same product type
// When passing multiple IDs, they cannot be of a mixed product type
// Retrieving the inventory data for an array of products can be useful when used in collection pages
const ids = [124810, 224812]
const { products, status } = useInventory({ ids, productType: 'Product' })

ids.forEach(productKey => {
  const { availableForSale, quantity, minOrder, maxOrder, price } = products[productKey] || {}
})

// A custom interval (in milliseconds) can be passed
const { products, status } = useInventory({ ids: [ id ], productType: 'Product', interval: 5000 })
const { availableForSale, quantity, minOrder, maxOrder, price } = products[id] || {}