A React Context provider for quickly and easily building a shopping cart using Next.js or any other React framework.
APACHE-2.0 License
npm
:
npm install @mrvautin/react-shoppingcart --save
yarn
:
yarn add @mrvautin/react-shoppingcart
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 . |
You may want to use hooks to check your backend server for things like:
discount
code is valid and not expiredprice
of an item is correctcartTotal
matches your expected value in databaseAvailable 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
.
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();
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
.
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
.
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
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>
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.
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)}
>
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
returns an object if a discount is applied else it returns an empty object {}
.
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)}
>
Used to remove a discount
from the cart.
const discount = {
id: 'discount1',
code: 'AMOUNT_DISCOUNT',
type: 'amount',
value: 2000,
}
<button
onClick={() => removeDiscount()}
>
shipping
returns an object if shipping is applied else it returns an empty object {}
.
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)}
>
Used to remove shipping
from the cart.
const shipping = {
description: 'Flat rate shipping',
costs: 1000,
}
<button
onClick={() => removeShipping()}
>
Used to completely empty the cart including items
, discounts
and metadata
.
<button
onClick={() => emptyCart()}
>
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)}
>
Used to clear whetever metadata
is currently set on the cart.
<button
onClick={() => clearMetadata()}
>
Returns whatever metadata
is currently set on the cart.
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.
Returns the total unique items in the cart. This ignores the quantity and simply counts all unique products in the cart.
This value is 0
by default. If shipping is added, the total shipping is caluculated and stored in this value.
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 %
.
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
.
This value stores the total amount of just the items. This is a total of the item price * the item quantity.
This value stores the net total taking into account any discounts. Eg: This value is: cartTotal
- totalDiscountAmount
= cartNetTotal
.
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
.
An example Next.js
project is stored in /example
. You can see the basics of using the component in this example project.
cd example
yarn install
yarn run dev
http://localhost:3000
Running tests with:
yarn run test