Introduction
Building a full-stack e-commerce application can be a rewarding project for honing your development skills. This step-by-step guide will help you create an e-commerce app with React, Redux Toolkit, Node.js, Express, MongoDB, and localStorage for managing the cart.
E-commerce has revolutionized the way businesses operate and customers shop. Creating an e-commerce application is not just a valuable skill but also an opportunity to build a real-world, high-impact project. This tutorial walks you through the process of developing a full-stack e-commerce app from scratch. The backend leverages the power of Node.js and Express to create APIs and connect to a MongoDB database, while the frontend uses React and Redux Toolkit to manage state efficiently. Additionally, the application uses localStorage to persist cart data, ensuring a seamless user experience. Whether you’re a beginner or an experienced developer, this guide will help you build a feature-rich e-commerce platform with functionality like product display, cart management, and more. By the end, you’ll have a robust application that you can deploy and expand with advanced features like authentication and payment gateways.
Step 1: Setting Up the Backend
1.1 Initialize the Project
- Create a new directory and navigate into it.
mkdir ecommerce-app && cd ecommerce-app
- Initialize a Node.js project:
npm init -y
1.2 Install Dependencies
Install the necessary backend dependencies:
npm install express mongoose dotenv body-parser cors
npm install --save-dev nodemon
1.3 Configure the Server
Create a file named server.js
in the root directory and set up the Express server:
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const dotenv = require('dotenv');
dotenv.config();
const app = express();
app.use(cors());
app.use(express.json());
// Connect to MongoDB
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log('MongoDB connected'))
.catch((err) => console.error(err));
// API routes
app.get('/', (req, res) => {
res.send('API is running...');
});
const productRoutes = require(‘./routes/productRoutes’);
const cartRoutes = require(‘./routes/cartRoutes’);
const customerRoutes = require(‘./routes/customerRoutes’);
const orderRoutes = require(‘./routes/orderRoutes’);
const orderDetailsRoutes = require(‘./routes/orderDetailsRoutes’);
app.use(‘/api/products’, productRoutes);
app.use(‘/api/cart’, cartRoutes);
app.use(‘/api/customers’, customerRoutes);
app.use(‘/api/orders’, orderRoutes);
app.use(‘/api/order-details’, orderDetailsRoutes);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
1.4 Create Models
Create a models
directory and add a Product.js
file for product schema:
const mongoose = require('mongoose');
const productSchema = mongoose.Schema({
name: { type: String, required: true },
price: { type: Number, required: true },
description: { type: String },
image: { type: String },
}, { timestamps: true });
module.exports = mongoose.model('Product', productSchema);
1.5 Add Routes
In a routes
directory, create a productRoutes.js
file:
const express = require('express');
const Product = require('../models/Product');
const router = express.Router();
// Get all products
router.get('/', async (req, res) => {
const products = await Product.find();
res.json(products);
});
module.exports = router;
Connect the routes in server.js
:
const productRoutes = require('./routes/productRoutes');
app.use('/api/products', productRoutes);
Step 2: Setting Up the Frontend
2.1 Initialize React Project
Create a new React application:
npx create-react-app frontend
cd frontend
2.2 Install Dependencies
Install the necessary packages for state management and API calls:
npm install @reduxjs/toolkit react-redux axios react-router-dom
2.3 Set Up Redux Toolkit
Create a features
directory in src
and add a cartSlice.js
file:
import { createSlice } from '@reduxjs/toolkit';
const cartSlice = createSlice({
name: 'cart',
initialState: {
cartItems: JSON.parse(localStorage.getItem('cartItems')) || [],
},
reducers: {
addToCart: (state, action) => {
const item = action.payload;
const existingItem = state.cartItems.find((x) => x._id === item._id);
if (existingItem) {
existingItem.qty += item.qty;
} else {
state.cartItems.push(item);
}
localStorage.setItem('cartItems', JSON.stringify(state.cartItems));
},
removeFromCart: (state, action) => {
state.cartItems = state.cartItems.filter((x) => x._id !== action.payload);
localStorage.setItem('cartItems', JSON.stringify(state.cartItems));
},
},
});
export const { addToCart, removeFromCart } = cartSlice.actions;
export default cartSlice.reducer;
2.4 Configure Redux Store
In src
, create a store.js
file:
import { configureStore } from '@reduxjs/toolkit';
import cartReducer from './features/cartSlice';
const store = configureStore({
reducer: {
cart: cartReducer,
},
});
export default store;
Wrap the App
component with the Provider
in index.js
:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Step 3: Fetch and Display Products
3.1 Create API Service
Create a services
directory in src
and add api.js
:
import axios from 'axios';
const API = axios.create({ baseURL: 'http://localhost:5000/api' });
export const fetchProducts = () => API.get('/products');
3.2 Display Products
In the src
directory, create a components
folder and add a ProductList.js
file:
import React, { useEffect, useState } from 'react';
import { fetchProducts } from '../services/api';
const ProductList = () => {
const [products, setProducts] = useState([]);
useEffect(() => {
const getProducts = async () => {
const { data } = await fetchProducts();
setProducts(data);
};
getProducts();
}, []);
return (
<div>
{products.map((product) => (
<div key={product._id}>
<h3>{product.name}</h3>
<p>{product.price}</p>
<button>Add to Cart</button>
</div>
))}
</div>
);
};
export default ProductList;
3.3 Add to Cart Functionality
Connect the addToCart
action from Redux:
import { useDispatch } from 'react-redux';
import { addToCart } from '../features/cartSlice';
const ProductList = () => {
const dispatch = useDispatch();
const handleAddToCart = (product) => {
dispatch(addToCart({ ...product, qty: 1 }));
};
return (
<div>
{products.map((product) => (
<div key={product._id}>
<h3>{product.name}</h3>
<p>{product.price}</p>
<button onClick={() => handleAddToCart(product)}>Add to Cart</button>
</div>
))}
</div>
);
};
Step 4: Final Touches
- Cart Page: Create a
Cart.js
component to display cart items and allow quantity updates or removal. - Styling: Use CSS frameworks like Bootstrap or TailwindCSS for a professional UI.
- Deployment: Deploy the backend on services like Heroku and the frontend on platforms like Netlify or Vercel.
Summary
This guide provided a comprehensive walkthrough of building a full-stack e-commerce application. By leveraging React-Redux Toolkit for state management, Node.js and Express for the backend, and MongoDB for data storage, you’ve created a scalable and robust application. The inclusion of localStorage ensures seamless cart management. Expand the project further with features like user authentication, payment integration, and order history for a complete e-commerce experience.