A beginner-friendly shopping cart demo built with modern frontend tooling and architecture. It is designed for learning React component design, Redux Toolkit state management, TypeScript typing patterns, and practical routing in a clean and reusable structure.
- Live Demo: https://shopmate-redux-toolkit.vercel.app/
Shopmate Redux Toolkit is a frontend-only e-commerce/cart learning project.
It demonstrates:
- Component-driven UI with reusable cards and layout pieces.
- Global cart state with Redux Toolkit.
- Route-based pages with React Router.
- Strict TypeScript types (no
any) for safer code. - Vite for fast local development and production builds.
If you are learning modern React architecture, this repository is a practical reference you can run and modify quickly.
- Project Summary
- Tech Stack
- Features
- How the App Works
- Project Structure
- Routes
- State Management Walkthrough
- Component Walkthrough
- TypeScript Design
- API and Backend Information
- Environment Variables (.env)
- How to Run the Project
- Available Scripts
- How to Reuse This in Other Projects
- Code Examples
- Keywords and Concepts
- Troubleshooting
- Conclusion
- License
- Happy Coding! π
- Vite: Fast bundler/dev server.
- React 19: UI rendering and component model.
- TypeScript 5: Static typing and safer refactoring.
- Redux Toolkit: Predictable and concise global state logic.
- React Redux: Hooks-based integration between React and Redux store.
- React Router DOM: Client-side routing (
/and/cart). - ESLint 9: Linting and code quality checks.
- Product listing page with static product catalog.
- Add to cart and remove from cart actions.
- Cart total and item count updates in real time.
- Header cart counter synced with global store.
- Route-level page switching with preserved state.
- Reusable presentational components (
ProductCard,CartCard,Header). - Custom hook for dynamic document title updates.
- SEO-ready metadata in
index.html.
- App bootstraps in
src/main.tsx. - Redux
Providerwraps the app so all components can access the store. - Router wraps the app, enabling page routes.
- Home page renders product list.
- Each product card checks whether product exists in cart state.
- Clicking "Add To Cart" dispatches
addaction. - Clicking "Remove" dispatches
removeaction. - Cart page reads
cartListandtotalfrom store and renders cart cards. - Header always reads cart count from store for instant sync.
shopmate-redux/
βββ public/
β βββ assets/images/ # Product images
β βββ robots.txt
β βββ vite.svg # App icon/logo used in metadata and header
βββ src/
β βββ components/
β β βββ Header.tsx
β β βββ ProductCard.tsx
β β βββ CartCard.tsx
β β βββ index.ts
β β βββ *.css
β βββ hooks/
β β βββ useTitle.ts
β βββ pages/
β β βββ Home.tsx
β β βββ Cart.tsx
β β βββ index.ts
β βββ routes/
β β βββ AllRoutes.tsx
β βββ store/
β β βββ cartSlice.ts
β β βββ store.ts
β β βββ hooks.ts
β βββ types/
β β βββ product.ts
β βββ App.tsx
β βββ main.tsx
β βββ index.css
β βββ App.css
βββ index.html
βββ package.json
βββ tsconfig*.json
βββ vite.config.ts
βββ eslint.config.mjs| Route | Page | Purpose |
|---|---|---|
/ |
Home | Shows all products and add/remove button state |
/cart |
Cart | Shows selected cart items and total price |
Global state is defined in src/store/cartSlice.ts:
cartList: Product[]stores selected products.total: numberstores total cart value.
Reducers:
add(state, action)remove(state, action)
Store setup:
src/store/store.tsregisterscartStatereducer.
Typed hooks:
src/store/hooks.tsexportsuseAppDispatchanduseAppSelector.
Why this matters:
- Better DX with autocompletion and type safety.
- Reusable cart logic across any component/page.
- Cleaner separation of UI and business logic.
- Shows logo, navigation links, and cart count.
- Uses
useAppSelectorto readcartState.cartList.length.
- Receives a
productprop. - Checks if product is already in cart.
- Toggles between "Add To Cart" and "Remove".
- Displays product in cart view.
- Allows removing product from cart.
- Holds local static
productsdata. - Renders
ProductCardlist.
- Reads cart list and total from global store.
- Renders all selected
CartCarditems.
- Small custom hook to update document title per page.
This project uses strict and explicit typings.
Core model:
export interface Product {
id: number;
name: string;
price: number;
image: string;
}Usage examples:
- Props are typed (
ProductCardProps,CartCardProps). - Redux action payloads are typed (
PayloadAction<Product>). - Store selector and dispatch are strongly typed.
This project currently has:
- No backend server.
- No database.
- No external API integration.
Product data is static and stored directly in src/pages/Home.tsx.
If you want to add backend later, typical options are:
- REST API (Node.js/Express, Laravel, Django, etc.)
- Headless CMS
- Firebase/Supabase
This project does not require any .env file to run.
If you integrate APIs later, create one of these:
.env.env.local
Example:
VITE_API_BASE_URL=https://api.example.com
VITE_APP_NAME=Shopmate Redux ToolkitIn Vite, only variables prefixed with VITE_ are exposed to client code.
Usage example:
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;- Node.js 18+ recommended.
- npm (comes with Node.js).
- Clone repository:
git clone https://github.com/arnobt78/Shopping-ReduxToolkit--React-Fundamental-Project-19.git
cd Shopping-ReduxToolkit--React-Fundamental-Project-19- Install dependencies:
npm install- Start dev server:
npm run dev- Open the local URL shown in terminal (usually
http://localhost:5173).
npm run dev: Run Vite dev server.npm run build: Type-check then build production assets.npm run preview: Preview production build locally.npm run lint: Run ESLint on the codebase.
You can copy or adapt these reusable pieces:
- Redux setup pattern:
store.ts+ typed hooks + feature slice.
- Typed component props pattern:
interface Props+ explicit function component signature.
- Route organization pattern:
- central
AllRoutes.tsx+ page barrel exports.
- central
- Custom hook pattern:
useTitlestyle small utility hooks.
Recommended extraction order:
- Copy
types/models. - Copy
store/and connect withProvider. - Port feature components and pages.
- Replace static data with API data.
import { add } from "../store/cartSlice";
import { useAppDispatch } from "../store/hooks";
const dispatch = useAppDispatch();
dispatch(add(product));import { useAppSelector } from "../store/hooks";
const total = useAppSelector((state) => state.cartState.total);<Route path="/wishlist" element={<Wishlist />} />- Redux Toolkit
- Global State Management
- Slice Reducers
- Typed React Hooks
- React Router
- Vite Build Tool
- TypeScript Strict Mode
- Reusable Components
- Frontend Architecture
- Educational React Project
Use a different port:
npm run dev -- --port 5174Run:
npm run lintRun a clean install:
rm -rf node_modules package-lock.json
npm install
npm run buildThis project is a complete and clean learning resource for modern React with Redux Toolkit and TypeScript.
You can use it to:
- Understand end-to-end state flow.
- Practice typed React patterns.
- Learn reusable frontend architecture.
- Extend into real API-backed commerce features.
This project is licensed under the MIT License. Feel free to use, modify, and distribute the code as per the terms of the license.
This is an open-source project - feel free to use, enhance, and extend this project further!
If you have any questions or want to share your work, reach out via GitHub or my portfolio at https://www.arnobmahmud.com.
Enjoy building and learning! π
Thank you! π

