Examples
Updated over a week ago

๐Ÿšง Important

Make sure to adjust the examples below accordingly to your project and store's platform.

Read more about platforms considerations here.

Creating a AddToCartButton component

AddToCartButton.js

import React from 'react' import { useCartState, useCartActions } from 'frontend-checkout' import LoadingSpinner from 'Components/LoadingSpinner' import './styles.css' // Button states const IDLE = 'idle' const LOADING = 'loading' const SOLD_OUT = 'sold out' const ERROR = 'error' // Error message duration const THREE_SECONDS = 3 * 1000 const AddToCart = ({ id, children }) => { const [buttonState, setButtonState] = React.useState(IDLE) const { inventory } = useCartState() const { addItems, isProductAvailableForSale } = useCartActions() React.useEffect( function setSoldOutStateIfItemIsNotAvailable() { if (inventory.status === LOADING || inventory.status === ERROR) return const availableForSale = isProductAvailableForSale({ id: variantId, type: 'ProductVariant', }) if (!availableForSale) setButtonState(SOLD_OUT) }, [inventory.status], ) function clearError() { setButtonState(IDLE) } async function handleAddItemToCart() { setButtonState(LOADING) try { await addItems({ id, quantity: 1 }) setButtonState(IDLE) } catch (e) { setButtonState(ERROR) setTimeout(clearError, THREE_SECONDS) // Remove error message after 3 seconds. } } if (buttonState === LOADING) return ( <button className="AddToCart"> <LoadingSpinner /> </button> ) if (buttonState === SOLD_OUT) return ( <button className="AddToCart AddToCart--sold" disabled> Sold out </button> ) if (buttonState === ERROR) return ( <button className="AddToCart" onClick={clearError}> Adding failed </button> ) return ( <button className="AddToCart" onClick={handleAddItemToCart}> {children} </button> ) } export default AddToCart

Creating a CheckoutLink component

JSX

import React from 'react' import { useCartState } from 'frontend-checkout' import './styles.css' const CheckoutLink = ({ children }) => { const { checkoutUrl } = useCartState() return ( <a className="CheckoutLink" href={checkoutUrl}> {children} </a> ) } export default CheckoutLink

Creating a ItemQuantityChange component

ItemQuantity.js

import React from 'react'
import { useCartState, useCartActions } from 'frontend-checkout'
import LoadingSpinner from 'Components/LoadingSpinner'

import './styles.css'

// Button states
const IDLE = 'idle'
const LOADING = 'loading'
const SOLD_OUT = 'sold out'
const ERROR = 'error'

// Error message duration
const THREE_SECONDS = 3 * 1000

const AddToCart = ({ id, children }) => {
const [buttonState, setButtonState] = React.useState(IDLE)

const { inventory } = useCartState()
const { addItems, isProductAvailableForSale } = useCartActions()

React.useEffect(
function setSoldOutStateIfItemIsNotAvailable() {
if (inventory.status === LOADING || inventory.status === ERROR) return

const availableForSale = isProductAvailableForSale({
id: variantId,
type: 'ProductVariant',
})

if (!availableForSale) setButtonState(SOLD_OUT)
},
[inventory.status],
)

function clearError() {
setButtonState(IDLE)
}

async function handleAddItemToCart() {
setButtonState(LOADING)
try {
await addItems({ id, quantity: 1 })
setButtonState(IDLE)
} catch (e) {
setButtonState(ERROR)
setTimeout(clearError, THREE_SECONDS) // Remove error message after 3 seconds.
}
}

if (buttonState === LOADING)
return (
<button className="AddToCart">
<LoadingSpinner />
</button>
)

if (buttonState === SOLD_OUT)
return (
<button className="AddToCart AddToCart--sold" disabled>
Sold out
</button>
)

if (buttonState === ERROR)
return (
<button className="AddToCart" onClick={clearError}>
Adding failed
</button>
)

return (
<button className="AddToCart" onClick={handleAddItemToCart}>
{children}
</button>
)
}

export default AddToCart

Creating a change item variant component

CartPage.js

import React from 'react'
import { useCartState } from 'frontend-checkout'

import './styles.css'

const CartPage = () => {
const { items } = useCartState()

return (
<CartContainer>
{items.map((item) => (
<CartItem key={item.id} item={item} />
))}
</CartContainer>
)
}

export default CartPage

CartPage.js

import React, { useEffect, useState } from 'react'
import { useCartActions } from 'frontend-checkout'

import './styles.css'

const CartItem = ({ item }) => {
const { fetchProduct } = useCartActions()
const [variants, setVariants] = useState([])

// Shopify Storefront API (GraphQL)
const productId = item.variant.product.id // product id must be used in GraphQL API (Variant and CheckoutLineItem id will not work)

// Shopify AJAX API (REST)
const productId = item.handle // product handle must be used in REST API

useEffect(
async function getProductVariants() {
const product = await fetchProduct(productId)

if (product == null) return

const { variants } = product

setVariants(variants)
},
[productId, fetchProduct, setVariants],
)

return (
<CartItemContainer>
<CartItemTitle item={item} />
<ItemQuantity item={item} />
<VariantsDropdown itemId={item.id} quantity={item.quantity} variants={variants} />
</CartItemContainer>
)
}

export default CartItem

CartPage.js

import React, { useEffect, useState } from 'react'
import { useCartActions } from 'frontend-checkout'

import './styles.css'

const VariantsDropdown = ({ itemId, quantity, variants }) => {
const { addItems, removeItems } = useCartActions()

async function handleVariantChange(variant) {
// we can't update existing item in cart
// we need to remove and then add new variant
await removeItems(itemId)

await addItems({ id: variant.id, quantity })
}

return (
<VariantsDropdownContainer>
{variants.map((variant) => (
<VariantsDropdownItem variant={variant} onSelect={handleVariantChange} />
))}
</VariantsDropdownContainer>
)
}

export default VariantsDropdown

Updating cart attribute

CartPage.js

import React from 'react'
import { useCartState, useCartActions } from 'frontend-checkout'

import './styles.css'

const CartPage = () => {
const { updateCart } = useCartActions()
const { attributes } = useCartState()

async function addTestAttrToCart() {
// updateCart({ attributes: {}, note: '', items: [] })
// this method is able to add/update cart attributes, note as well
// as item quantities (all parameters are optional).
await updateCart({ attributes: { test: 'test' } })
}

return (
<CartContainer>
<button onClick={addTestAttrToCart}>Add Test Attr</button>
{Object.keys(attributes).map(attributesKey => {
return <p key={someRandomId}>{attributesKey}: {attributes[attributesKey]}</p>
})}
</CartContainer>
)
}

export default CartPage
Did this answer your question?