Hello guys how are you? Welcome back to my blog. Today in this blog I am going to Creating an Ecommerce Website in Angular 18 using Bootstrap 5.
Angular 18 came . If you are new then you must check below two links:
Now guys here is the complete code snippet link and please follow carefully:
1. Setting Up the Angular Project
First, ensure you have Angular CLI installed. If not, install it using npm:
npm install -g @angular/cli ng new ecommerce-app cd ecommerce-app npm install bootstrap@5.3.0 npm install @fortawesome/fontawesome-free
In your angular.json file, add Bootstrap CSS & Icons:
"styles": [ "node_modules/@fortawesome/fontawesome-free/css/all.min.css", "node_modules/bootstrap/dist/css/bootstrap.min.css", "src/styles.css" ], "scripts": []
2. Setting Up Components
Create essential components for your e-commerce site, such as header, footer, product list, product detail, cart, checkout etc.
ng generate component components/header ng generate component components/footer ng generate component components/product-list ng generate component components/product-detail ng generate component components/cart ng generate component components/checkout
3. Implementing the Header Component
Update the header.component.html:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" routerLink="/">E-Commerce</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" routerLink="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/products">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/cart">Cart</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
</form>
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="#"><i class="fas fa-search"></i></a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/wishlist"><i class="fas fa-heart"></i></a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/cart"><i class="fas fa-shopping-cart"></i></a>
</li>
</ul>
</div>
</nav>
<div class="header-image">
<div class="overlay">
<h1 class="display-4">Welcome to Our E-Commerce Store</h1>
<p class="lead">Discover our amazing products and deals.</p>
<a routerLink="/products" class="btn btn-primary btn-lg">Shop Now</a>
</div>
</div>
Update the header.component.ts:
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-header',
standalone: true,
imports: [RouterLink],
templateUrl: './header.component.html',
styleUrl: './header.component.css'
})
export class HeaderComponent {
}
Update the header.component.css:
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
}
.nav-link {
font-size: 1.2rem;
margin-right: 1rem;
}
.form-inline {
flex-grow: 1;
}
.form-control {
margin-right: 0.5rem;
}
.navbar-nav.ml-auto .nav-item .nav-link {
font-size: 1.4rem;
}
.navbar-nav.ml-auto .nav-item .nav-link i {
margin-right: 0.5rem;
}
.header-image {
position: relative;
background: url('https://via.placeholder.com/1920x600') no-repeat center center;
background-size: cover;
height: 60vh;
color: white;
}
.overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.overlay h1 {
font-size: 3rem;
font-weight: bold;
}
.overlay p {
font-size: 1.5rem;
margin-bottom: 1.5rem;
}
.overlay .btn {
font-size: 1.25rem;
padding: 0.75rem 1.5rem;
}
@media (max-width: 768px) {
.header-image {
height: 40vh;
}
.overlay h1 {
font-size: 2rem;
}
.overlay p {
font-size: 1.2rem;
}
.overlay .btn {
font-size: 1rem;
padding: 0.5rem 1rem;
}
}
4. Product List Component
Update product-list.component.html to include some mock products:
<div class="container mt-4">
<div class="row">
<div class="col-md-4">
<div *ngIf="product">
<img src="https://via.placeholder.com/150" class="card-img-top" alt="{{ product.name }}">
<h2>{{ product.name }}</h2>
<p>Price: ${{ product.price }}</p>
<button class="btn btn-primary">Add to Cart</button>
</div>
<div *ngIf="!product">
<p>Product not found.</p>
</div>
</div>
</div>
</div>
Update product-list.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-product-detail',
standalone: true,
imports: [CommonModule, RouterLink],
templateUrl: './product-detail.component.html',
styleUrl: './product-detail.component.css'
})
export class ProductDetailComponent {
productId: number;
product: any;
products = [
{ id: 1, name: 'Product 1', price: 100 },
{ id: 2, name: 'Product 2', price: 200 },
{ id: 3, name: 'Product 3', price: 300 },
];
constructor(private route: ActivatedRoute) {
this.productId = this.route.snapshot.params['id'];
this.product = this.products.find(p => p.id === +this.productId);
}
}
5. Header Component
Update header.component.html
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" routerLink="/">E-Commerce</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" routerLink="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/products">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/cart">Cart</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
</form>
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="#"><i class="fas fa-search"></i></a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/wishlist"><i class="fas fa-heart"></i></a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/cart"><i class="fas fa-shopping-cart"></i></a>
</li>
</ul>
</div>
</nav>
<div class="header-image">
<div class="overlay">
<h1 class="display-4">Welcome to Our E-Commerce Store</h1>
<p class="lead">Discover our amazing products and deals.</p>
<a routerLink="/products" class="btn btn-primary btn-lg">Shop Now</a>
</div>
</div>
Update header.component.ts
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-header',
standalone: true,
imports: [RouterLink],
templateUrl: './header.component.html',
styleUrl: './header.component.css'
})
export class HeaderComponent {
}
Update header.component.css
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
}
.nav-link {
font-size: 1.2rem;
margin-right: 1rem;
}
.form-inline {
flex-grow: 1;
}
.form-control {
margin-right: 0.5rem;
}
.navbar-nav.ml-auto .nav-item .nav-link {
font-size: 1.4rem;
}
.navbar-nav.ml-auto .nav-item .nav-link i {
margin-right: 0.5rem;
}
.header-image {
position: relative;
background: url('https://via.placeholder.com/1920x600') no-repeat center center;
background-size: cover;
height: 60vh;
color: white;
}
.overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.overlay h1 {
font-size: 3rem;
font-weight: bold;
}
.overlay p {
font-size: 1.5rem;
margin-bottom: 1.5rem;
}
.overlay .btn {
font-size: 1.25rem;
padding: 0.75rem 1.5rem;
}
@media (max-width: 768px) {
.header-image {
height: 40vh;
}
.overlay h1 {
font-size: 2rem;
}
.overlay p {
font-size: 1.2rem;
}
.overlay .btn {
font-size: 1rem;
padding: 0.5rem 1rem;
}
}
6. Footer Component
//footer.component.html
<footer class="bg-light text-center text-lg-start mt-5">
<div class="container p-4">
<div class="row">
<div class="col-lg-6 col-md-12 mb-4 mb-md-0">
<h5 class="text-uppercase">About Us</h5>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iste atque ea quis molestias.
Fugiat pariatur maxime quis culpa corporis vitae repudiandae aliquam voluptatem veniam,
est atque cumque eum delectus sint!
</p>
</div>
<div class="col-lg-3 col-md-6 mb-4 mb-md-0">
<h5 class="text-uppercase">Links</h5>
<ul class="list-unstyled mb-0">
<li>
<a href="#!" class="text-dark">Privacy Policy</a>
</li>
<li>
<a href="#!" class="text-dark">Terms of Service</a>
</li>
<li>
<a href="#!" class="text-dark">Contact Us</a>
</li>
<li>
<a href="#!" class="text-dark">FAQs</a>
</li>
</ul>
</div>
<div class="col-lg-3 col-md-6 mb-4 mb-md-0">
<h5 class="text-uppercase">Contact</h5>
<ul class="list-unstyled mb-0">
<li>
<p class="text-dark">1234 Street Name, City, State, 12345</p>
</li>
<li>
<p class="text-dark">Email: info.com</p>
</li>
<li>
<p class="text-dark">Phone: +1 234 567 890</p>
</li>
</ul>
</div>
</div>
</div>
<div class="text-center p-3" style="background-color: rgba(0, 0, 0, 0.2);">
© 2024 E-Commerce Website
</div>
</footer>
//footer.component.css
footer {
padding: 20px 0;
background-color: #f8f9fa;
color: #6c757d;
}
footer h5 {
margin-bottom: 1rem;
font-weight: bold;
}
footer p,
footer a {
margin-bottom: 0.5rem;
color: #6c757d;
}
footer a:hover {
color: #007bff;
text-decoration: none;
}
footer .text-center {
padding-top: 1rem;
padding-bottom: 1rem;
}
7. Cart Component
Update cart.component.html:
<div class="container mt-4">
<h2>Shopping Cart</h2>
<table class="table">
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of cartItems">
<td>{{ item.name }}</td>
<td>${{ item.price }}</td>
<td>{{ item.quantity }}</td>
<td>${{ item.price * item.quantity }}</td>
</tr>
</tbody>
</table>
<div class="text-right">
<button class="btn btn-success" [routerLink]="['/checkout']">Checkout</button>
</div>
</div>
Update cart.component.ts:
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-cart',
standalone: true,
imports: [CommonModule, RouterLink],
templateUrl: './cart.component.html',
styleUrl: './cart.component.css'
})
export class CartComponent {
cartItems = [
{ id: 1, name: 'Product 1', price: 100, quantity: 2 },
{ id: 2, name: 'Product 2', price: 200, quantity: 1 },
];
}
8. Checkout Component
update checkout.component.html
<div class="container mt-5">
<h2 class="mb-4">Checkout</h2>
<form>
<div class="row">
<div class="col-md-6 mb-3">
<label for="firstName" class="form-label">First Name</label>
<input type="text" class="form-control" id="firstName" required>
</div>
<div class="col-md-6 mb-3">
<label for="lastName" class="form-label">Last Name</label>
<input type="text" class="form-control" id="lastName" required>
</div>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" required>
</div>
<div class="mb-3">
<label for="address" class="form-label">Address</label>
<input type="text" class="form-control" id="address" required>
</div>
<div class="mb-3">
<label for="address2" class="form-label">Address 2</label>
<input type="text" class="form-control" id="address2">
</div>
<div class="row">
<div class="col-md-5 mb-3">
<label for="country" class="form-label">Country</label>
<select class="form-select" id="country" required>
<option value="">Choose...</option>
<option>United States</option>
<option>Canada</option>
<option>United Kingdom</option>
</select>
</div>
<div class="col-md-4 mb-3">
<label for="state" class="form-label">State</label>
<select class="form-select" id="state" required>
<option value="">Choose...</option>
<option>California</option>
<option>Texas</option>
<option>New York</option>
</select>
</div>
<div class="col-md-3 mb-3">
<label for="zip" class="form-label">Zip</label>
<input type="text" class="form-control" id="zip" required>
</div>
</div>
<h4 class="mb-3">Payment</h4>
<div class="my-3">
<div class="form-check">
<input id="credit" name="paymentMethod" type="radio" class="form-check-input" checked required>
<label class="form-check-label" for="credit">Credit card</label>
</div>
<div class="form-check">
<input id="debit" name="paymentMethod" type="radio" class="form-check-input" required>
<label class="form-check-label" for="debit">Debit card</label>
</div>
<div class="form-check">
<input id="paypal" name="paymentMethod" type="radio" class="form-check-input" required>
<label class="form-check-label" for="paypal">PayPal</label>
</div>
</div>
<div class="row gy-3">
<div class="col-md-6">
<label for="cc-name" class="form-label">Name on card</label>
<input type="text" class="form-control" id="cc-name" required>
<small class="text-muted">Full name as displayed on card</small>
</div>
<div class="col-md-6">
<label for="cc-number" class="form-label">Credit card number</label>
<input type="text" class="form-control" id="cc-number" required>
</div>
<div class="col-md-3">
<label for="cc-expiration" class="form-label">Expiration</label>
<input type="text" class="form-control" id="cc-expiration" required>
</div>
<div class="col-md-3">
<label for="cc-cvv" class="form-label">CVV</label>
<input type="text" class="form-control" id="cc-cvv" required>
</div>
</div>
<hr class="my-4">
<button class="w-100 btn btn-primary btn-lg" type="submit">Place Order</button>
</form>
</div>
9. Product Details Component
Update product-details.component.html:
<div class="container mt-4">
<div class="row">
<div class="col-md-4">
<div *ngIf="product">
<img src="https://via.placeholder.com/150" class="card-img-top" alt="{{ product.name }}">
<h2>{{ product.name }}</h2>
<p>Price: ${{ product.price }}</p>
<button class="btn btn-primary">Add to Cart</button>
</div>
<div *ngIf="!product">
<p>Product not found.</p>
</div>
</div>
</div>
</div>
Update product-details.component.ts:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-product-detail',
standalone: true,
imports: [CommonModule, RouterLink],
templateUrl: './product-detail.component.html',
styleUrl: './product-detail.component.css'
})
export class ProductDetailComponent {
productId: number;
product: any;
products = [
{ id: 1, name: 'Product 1', price: 100 },
{ id: 2, name: 'Product 2', price: 200 },
{ id: 3, name: 'Product 3', price: 300 },
];
constructor(private route: ActivatedRoute) {
this.productId = this.route.snapshot.params['id'];
this.product = this.products.find(p => p.id === +this.productId);
}
}
10. Setting Up Routing
Configure your app routing in app-routing.module.ts:
import { Routes } from '@angular/router';
import { ProductListComponent } from './components/product-list/product-list.component';
import { ProductDetailComponent } from './components/product-detail/product-detail.component';
import { CartComponent } from './components/cart/cart.component';
import { CheckoutComponent } from './components/checkout/checkout.component';
export const routes: Routes = [
{ path: '', component: ProductListComponent },
{ path: 'products', component: ProductListComponent },
{ path: 'product/:id', component: ProductDetailComponent },
{ path: 'cart', component: CartComponent },
{ path: 'checkout', component: CheckoutComponent },
{ path: '**', redirectTo: '', pathMatch: 'full' }
];
11. Use the Component Correctly in the Template
Ensure that you are using the component correctly in the template. For example, in the app.component.html
<app-header></app-header> <app-product-list></app-product-list> <app-footer></app-footer>
12. Start the Development Server
Sometimes, changes might not take effect immediately. Restart the Angular development server
ng serve
Open your browser and navigate to http://localhost:4200.
This setup provides a basic e-commerce website structure using Angular 18 and Bootstrap 5. You can expand and customize it further based on your requirements, such as adding authentication, connecting to a backend, and improving the UI/UX.
Note: Friends, In this post, I just tell the basic setup and things, you can change the code according to your requirements.
I will appreciate that if you will tell your views for this post. Nothing matters if your views will be good or bad because with your views, I will make my next posts more good and helpful.
Jassa
Thanks
