@mrvautin/react-shoppingcart
v1.0.4
Published
A React Context provider to quickly and easily build a shopping cart using Next.js or any other React framework.
Downloads
12
Maintainers
Readme
- 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 --save
yarn
:
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
discount
code is valid and not expired - The
price
of an item is correct - The
cartTotal
matches 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
id
anditemVariants
- 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 sameid
amditemVariants
.
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 sameid
amditemVariants
.
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
shoes1
but it may have anitemVariants
ofsize
ofUS11
in 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
itemVariants
ensure the sameid
anditemVariants
are 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