Build a Fully Functional Shopping Cart in Next.js + Chatgpt Using Context API
Building an e-commerce site in Next.js? You need a cart system that can:
✅ Add, remove, and update items
✅ Calculate total price
✅ Persist data using localStorage
✅ Support a clean and scalable architecture
https://www.youtube.com/watch?v=D2ZcEHXI7RI
🛠️ Step 1: Create the Cart Context
"use client";
import { createContext, useContext, useEffect, useState } from "react";
const CartContext = createContext();
export const CartProvider = ({ children }) => {
const [cart, setCart] = useState([]);
useEffect(() => {
const savedCart = JSON.parse(localStorage.getItem("cart")) || [];
setCart(savedCart);
}, []);
useEffect(() => {
localStorage.setItem("cart", JSON.stringify(cart));
}, [cart]);
const addToCart = (product) => {
setCart((prevCart) => {
const existingItem = prevCart.find((item) => item.id === product.id);
if (existingItem) {
return prevCart.map((item) =>
item.id === product.id ? { ...item, quantity: item.quantity + 1 } : item
);
} else {
return [...prevCart, { ...product, quantity: 1 }];
}
});
};
const removeFromCart = (id) => {
setCart((prevCart) => prevCart.filter((item) => item.id !== id));
};
const updateQuantity = (id, quantity) => {
setCart((prevCart) =>
prevCart.map((item) => (item.id === id ? { ...item, quantity } : item))
);
};
const totalPrice = cart.reduce((total, item) => total + item.price * item.quantity, 0);
const clearCart = () => setCart([]);
return (
<CartContext.Provider value={{ cart, addToCart, removeFromCart, updateQuantity, totalPrice, clearCart }}>
{children}
</CartContext.Provider>
);
};
export const useCart = () => useContext(CartContext);
📌 Step 2: Wrap the Application with CartProvider
🛒 Step 3: Add an "Add to Cart" Button to Your Products
'use client';
import Image from 'next/image';
const products = [
{
id: 1,
name: 'Wireless Headphones',
price: '$99.99',
image: 'https://via.placeholder.com/150',
},
{
id: 2,
name: 'Smart Watch',
price: '$149.99',
image: 'https://via.placeholder.com/150',
},
{
id: 3,
name: 'Gaming Mouse',
price: '$49.99',
image: 'https://via.placeholder.com/150',
},
{
id: 4,
name: 'Mechanical Keyboard',
price: '$129.99',
image: 'https://via.placeholder.com/150',
},
];
const ProductCard = () => {
const { addToCart } = useCart();
return (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 p-6">
{products.map((product) => (
<div key={product.id} className="border rounded-lg p-4 shadow-lg bg-white">
<Image
src={product.image}
alt={product.name}
width={150}
height={150}
className="w-full h-40 object-cover rounded-md"
/>
<h2 className="text-lg font-semibold mt-2">{product.name}</h2>
<p className="text-gray-600">{product.price}</p>
<button onClick={() => addToCart(product)} className="mt-3 bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600">
Add to Cart
</button>
</div>
))}
</div>
);
};
export default ProductCard;
🛍️ Step 4: Create the Cart Page
"use client";
import { useCart } from "../../context/CartContext";
const CartPage = () => {
const { cart, removeFromCart, updateQuantity, totalPrice, clearCart } = useCart();
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4">Shopping Cart</h1>
{cart.length === 0 ? (
<p>Your cart is empty</p>
) : (
<>
{cart.map((item) => (
<div key={item.id} className="flex justify-between items-center border-b py-2">
<div>
<h2>{item.name}</h2>
<p>${item.price}</p>
<input
type="number"
value={item.quantity}
min="1"
className="border p-1 w-16"
onChange={(e) => updateQuantity(item.id, parseInt(e.target.value))}
/>
</div>
<button className="bg-red-500 text-white px-3 py-1 rounded" onClick={() => removeFromCart(item.id)}>
Remove
</button>
</div>
))}
<h2 className="text-lg font-bold mt-4">Total: ${totalPrice.toFixed(2)}</h2>
<button className="bg-green-500 text-white px-4 py-2 mt-4 rounded" onClick={clearCart}>
Clear Cart
</button>
</>
)}
</div>
);
};
export default CartPage;