@mrvautin/react-shoppingcart v1.0.4
- Persistent local storage using React Context
- Works with Next, Gatsby, React
- Supports hooks to listen for events
- Written in Typescript
- Supports discount codes
- Supports shipping costs
- Supports product variants - Size, colour etc
- Supports cart metadata
View Demo.
Install
npm:
npm install @mrvautin/react-shoppingcart --saveyarn:
yarn add @mrvautin/react-shoppingcart Getting started
Add the Context
Wrap your app in the <CartProvider> (eg: Add to your _app.tsx):
import type { AppProps } from 'next/app';
import { CartProvider } from '@mrvautin/react-shoppingcart';
export default function App({ Component, pageProps }: AppProps) {
return (
<CartProvider>
<Component {...pageProps} />
</CartProvider>
);
}| Prop | Required | Description |
|---|---|---|
cartId | No | cartId for your cart storage. If nothing is supplied, react-shoppingcart is used. |
onItemAdd | No | Triggered an item is added to your cart using addItem. |
onItemUpdate | No | Triggered when items are updated in your cart using updateItemQuantity(). |
onItemRemove | No | Triggered on items are removed from your cart using removeItem(). |
onDiscountAdd | No | Triggered when a discount is added using addDiscount(). |
onDiscountRemove | No | Triggered when a discount is removed using removeDiscount(). |
onShippingAdd | No | Triggered when a shipping is added using addShipping(). |
onShippingRemove | No | Triggered when a shipping is removed using removeShipping(). |
onEmptyCart | No | Triggered on emptyCart() is called. |
onMetadataUpdate | No | Triggered when metadata is changed in your cart using setMetadata() or clearMetadata(). |
currency | No | Used to set the currency formatting of the discount. Defaults to USD. |
locale | No | Used to set the locale formatting of the discount. Defaults to en-US. |
Listening to a hook
You may want to use hooks to check your backend server for things like:
- A
discountcode is valid and not expired - The
priceof an item is correct - The
cartTotalmatches your expected value in database
Available Hooks are: onItemAdd, onItemUpdate, onItemRemove, onDiscountAdd, onDiscountRemove, onShippingAdd, onShippingRemove, onEmptyCart and onMetadataUpdate.
On the <CartProvider> you can add any hooks you need to listen on:
import type { AppProps } from 'next/app';
import { CartProvider } from '@mrvautin/react-shoppingcart';
export default function App({ Component, pageProps }: AppProps) {
return (
<CartProvider onItemAdd={cart => alert(cart)}>
{children}
</CartProvider>
);
}Keeping in mind that any cart values can be altered by the user by changing their
localstorage.
Add to your Component
import { useCart } from '@mrvautin/react-shoppingcart';
...
const {
items,
addItem,
removeItem,
getItem,
updateItemQuantity,
addDiscount,
removeDiscount,
setMetadata,
clearMetadata,
metadata,
totalShippingAmount,
totalDiscountAmount,
totalItemsAmount,
discount,
cartDiscountText,
totalNumberItems
totalUniqueItems,
cartTotal,
cartNetTotal,
emptyCart,
} = useCart();Usage
addItem
The first argument is a product object to add to the cart. Minimum values required are:
| Prop | Required | Description |
|---|---|---|
id | Yes | id for the item being added to the cart |
name | Yes | name for the items. |
price | Yes | price formatted in whole number. Eg: $10.00 would be 1000. |
The second arguement is an option quantity. If not supplied, 1 is added by default.
const product = {
id: 'shoes1',
name: 'Running shoes',
price: 1000,
}
<button
onClick={() => addItem(product)}
/>
// Adding 5 items
<button
onClick={() => addItem(product, 5)}
/>Note: If the exact same item (eg: Same
idanditemVariants- if supplied) is added twice, the quantity for the item is increased by1.
removeItem
Used to remove an item from the cart.
const product = {
id: 'shoes1',
name: 'Running shoes',
price: 1000,
}
<button
onClick={() => addItem(product)}
/>
// Adding 5 items
<button
onClick={() => addItem(product, 5)}
/>Note: If using
itemVariants, you will need to supply the sameidamditemVariants.
getItem
Used to get an item which has been already added to the cart.
const product = {
id: 'shoes1',
name: 'Running shoes',
price: 1000,
}
<button
onClick={() => getItem(product)}
/>Note: If using
itemVariants, you will need to supply the sameidamditemVariants.
items
items is an array property which stores a list of items in the cart.
// You can loop the items
<div>
<h1>Cart</h1>
{items.map((item) => (
<div key={item.id}>
<div>Name: {item.name} - Quantity: {item.quantity}</div>
</div>
))}
</div>itemVariants
const product = {
id: 'shoes1',
name: 'Running shoes',
price: 1000,
itemVariants: [
{
size: 'US11'
},
{
color: 'white'
}
],
}
<button
onClick={() => addItem(product)}
>Note this function allows for a single product ID to be used per product but multiple variations to it. For instance, you may have a single product with an ID of
shoes1but it may have anitemVariantsofsizeofUS11in the example above. This allows the same product to be added to the cart multiple times despite having a different variant set.
updateItemQuantity
Used to update the quantity of an item already in the cart.
const product = {
id: 'shoes1',
name: 'Running shoes',
price: 1000,
itemVariants: [
{
size: 'US11'
},
{
color: 'white'
}
],
}
<button
onClick={() => updateItemQuantity(product, 'increase', 2)}
>removeItem
Used to remove an item already in the cart.
const product = {
id: 'shoes1',
name: 'Running shoes',
price: 1000,
itemVariants: [
{
size: 'US11'
},
{
color: 'white'
}
],
}
<button
onClick={() => removeItem(product)}
>Note: If using
itemVariantsensure the sameidanditemVariantsare supplied in theremoveItem()call.
discount
discount returns an object if a discount is applied else it returns an empty object {}.
addDiscount
Used to add a discount to the cart. You will want to ensure this discount is allowed and valid on your backend. You can do this by listening on the onDiscountAdd event to validate and remove if required.
| Prop | Required | Description |
|---|---|---|
id | Yes | id for the discount |
code | Yes | code for the discount being added. This would be what is advised to the customer and entered at checkout. |
type | Yes | type of discount. Allowed values are: amount and percent. |
value | Yes | value to be discounted in whole number. Eg: 1000 is $10.00 discount or 10% depending on type. |
const discount = {
id: 'discount1',
code: 'AMOUNT_DISCOUNT',
type: 'amount',
value: 2000,
}
<button
onClick={() => addDiscount(discount)}
>removeDiscount
Used to remove a discount from the cart.
const discount = {
id: 'discount1',
code: 'AMOUNT_DISCOUNT',
type: 'amount',
value: 2000,
}
<button
onClick={() => removeDiscount()}
>shipping
shipping returns an object if shipping is applied else it returns an empty object {}.
addShipping
Used to add shipping to the cart. You will want to ensure this shipping is allowed and valid on your backend. You can do this by listening on the onShippingAdd or onShippingRemove event to validate and remove if required.
| Prop | Required | Description |
|---|---|---|
description | Yes | description for the discount being added. This would be what is advised to the customer and entered at checkout. |
costs | Yes | Shipping costs to be adding as a whole number. Eg: 1000 is $10.00 |
const shipping = {
description: 'Flat rate shipping',
costs: 1000,
}
<button
onClick={() => addShipping(shipping)}
>removeShipping
Used to remove shipping from the cart.
const shipping = {
description: 'Flat rate shipping',
costs: 1000,
}
<button
onClick={() => removeShipping()}
>emptyCart
Used to completely empty the cart including items, discounts and metadata.
<button
onClick={() => emptyCart()}
>setMetadata
Used to add metadata to the cart. This could be used to store an order ID, customer ID or notes about shipping etc.
const metadata = {
customerId: '1234',
notes: 'Leave on door step',
};
<button
onClick={() => setMetadata(metadata)}
>clearMetadata
Used to clear whetever metadata is currently set on the cart.
<button
onClick={() => clearMetadata()}
>metadata
Returns whatever metadata is currently set on the cart.
totalNumberItems
Returns the total number of items in the cart. This adds the quantity of all items in the cart to give a total number of items being purchased.
totalUniqueItems
Returns the total unique items in the cart. This ignores the quantity and simply counts all unique products in the cart.
totalShippingAmount
This value is 0 by default. If shipping is added, the total shipping is caluculated and stored in this value.
totalDiscountAmount
This value is 0 by default. If a discount is added, the total discount is caluculated and stored in this value. Eg: If the discount is a percent, this value will store the total discounted $ based on the set %.
cartDiscountText
This value stores a nice discount value which can be displayed on the cart. Eg: If the discount is set to $20.00 then the text will be: $20.00 off. Depending on the currency and locale set, this same text in Euro will be: 20,00 € off.
totalItemsAmount
This value stores the total amount of just the items. This is a total of the item price * the item quantity.
cartNetTotal
This value stores the net total taking into account any discounts. Eg: This value is: cartTotal - totalDiscountAmount = cartNetTotal.
cartTotal
Returns the total value in the cart including totalDiscountAmount and totalShippingAmount. Essentially it's totalItemsAmount - totalDiscountAmount + totalShippingAmount = cartTotal. The value is in whole number. Eg: 1000 is $10.00.
Example
An example Next.js project is stored in /example. You can see the basics of using the component in this example project.
- Enter directory:
cd example - Install:
yarn install - Start up Next.js:
yarn run dev - Visit the example:
http://localhost:3000
Tests
Running tests with:
yarn run test