Bootstrap with Angular 18

Updated : 14/06/2024 danny

Bootstrap is the best known and most used CSS framework.

We will integrate Bootstrap version 5.3.3 into our Web Application.

For this we will use the Angular javascript framework version 18.0.2

Bootstrap avec Angular

What we are going to do

  • What is Bootstrap?
    We are going to talk about bootstrap and its usefulness in websites.
     
  • Creation of our Angular project
    We will use an existing project containing the essential functionality.
    The project was generated with Angular CLI and uses Routing and Lazy Loading.
     
  • Bootstrap prototype
    Why and how to create a Bootstrap prototype ?
     
  • Version 4 versus Version 5
    Which version of bootstrap should you choose ?
     
  • Integration with our Angular project
    How to integrate Bootstrap using Angular CLI ?
     
  • Perform the Tests
    We will test our application via unit and end-to-end testing integrated into Angular.
     
  • Source code
    For those in a hurry among you, the complete code of the project.
    https://github.com/ganatan/angular-react-bootstrap

 


What is Bootstrap?

The pages of a website are written using 3 types of computer languages .

  • HTML language
    Hyper Text Markup Language
    it allows you to create and represent the content of a web page and its structure.
  • CSS language
    Cascading Style Sheets
    it is used to describe the layout of a page.
  • Javascript language
    It allows you to create interactive features on the page.


There are many tools to simplify the life of a developer.
In particular CSS Frameworks which constitute, in a way, graphical toolboxes.

CSS Frameworks are extremely numerous, among these we could cite

  • Foundation
  • Materialize CSS
  • Bootstrap
  • Pure

Bootstrap is one of the most famous and widely used CSS frameworks.

Bootstrap has been under open source license since 2011.
It is therefore free to use .

It allows you to create responsive sites.
This means that it allows a website to be adapted to all kinds of devices (computer, smartphone or tablet).

The current version is version 5.3.3


Creating the Angular project

To be able to continue this tutorial we obviously need to have certain elements

  • Node.js : The javascript platform
  • Git : Version management software.
  • Angular CLI : The tool provided by Angular.
  • Visual Studio Code : A code editor.

You can consult the following tutorial which explains in detail how to do it


We will use an existing project whose characteristics are

  • Generated with Angular CLI
  • Routing
  • Lazy loading

You can install this project on your workstation using the following commands.

# Create a demo directory (the name here is arbitrary)
mkdir demo

# Go to this directory
cd demo

# Get the source code on your workstation
git clone https://github.com/ganatan/angular-lazy-loading.git

# Go to the directory that was created
cd angular-lazy-loading
cd angular

# Run the installation of dependencies (or libraries)
npm install

# Run the program
npm run start

# Check how it works by running the command in your browser
http://localhost:4200/

Why Create a Bootstrap Prototype?

To simplify, there are 3 types of web developer

  • Frontend
  • Backend
  • Full stack

We could add a 4th profession

  • Web designer


Still simplifying, the first 3 deal with the logical part and the fourth with the graphic part.

This is why we will first create a graphic prototype.
This prototype will serve as the basis for the design phase of your website.

Some reasons for this choice.

  • It is more difficult and expensive to make changes in code than in a prototype.
  • If you are brought to work in a team, it is easier to know who is doing what.
  • There are many prototyping tools.
  • It facilitates the evolution and improvement of the interface.
  • It is faster and easier to present a prototype to a potential customer.

SO.

To do this, it is not necessary to know Angular.
Only knowledge of HTML, CSS and a little javascript will be required.


It will even be possible to subcontract to a Web Designer or graphic designer partner.

These are some of the elements of this prototype that we will integrate into our Angular application.

The architecture of this prototype and the choice of names is of course arbitrary.
You can adapt it to your liking.


Quick summary of prototyping

The design of a website will go through several stages.
One of them is prototyping .
Prototyping consists of creating a non-definitive copy of what the final product may be.
It allows to design a User Interface or UI (User Interface)

There are 2 stages of prototyping.

  • Horizontal prototyping
    Create a static model.
    Draw a diagram (wireframe)
    Define zones and components
  • Vertical prototyping
    Integrate Features

In this tutorial, we will simply create a static model.


How to create a bootstrap prototype?

Just to understand what we are doing, we will not use any prototyping tools.
We will design this prototype manually and from scratch .

The directory that will contain this prototype will be UI or User Interface (for User Interface).

An image will allow us to have an overview of our prototype within our Angular application.

Prototype Bootstrap

Let's get to practice.
We will search the web for all the necessary elements which we will place in the tree of our Angular project.

We will ultimately obtain the following tree structure.

|-- node_modules/          (contains the node libraries) 
|-- src/          (contains the source code of our angular application) 
|-- ui/                    ( contains our bootstrap prototype)
    |-- assets
        |-- bootstrap
            |-- css
            |-- js
        |-- fontawesome
            |-- css
            |-- js
            |-- webfonts
        |-- params
            |-- css
            |-- images
            |-- js
package.json

Version 4 vs Version 5

Bootstrap 4 is very nice.
But version 5 was released on June 16, 2020.

The latest version is version 5.3.3

It's interesting to see that this version brings two major changes.

  • Removing Jquery.
    And consequently the use of Vanilla javascript (in other words javascript nothing but javascript)
  • The abandonment of compatibility with IE 10 and 11 (Internet Explorer)
    It wasn't too early

The final project will use version 5, I tested it, it works, so why not!

To hell with caution.
We'll have time to be careful when we're dead.

 


The elements of the prototype

So let’s get started!

In the ui directory create an assets directory.
In this assets directory create the following 3 directories

  • bootstrap
  • fontawesome
  • params

Let's now collect the different elements useful for our prototype.

Bootstrap elements

 

  • Go to the bootstrap site (donwload part)
    https://v5.getbootstrap.com/docs/5.3/getting-started/download/
  • Download the compiled CSS and JS files ( compiled CSS et JS / download )
  • The file we are interested in is bootstrap-5.3.3-dist.zip
  • Unzip the bootstrap-5.3.3-dist.zip file
  • Copy the CSS and JS directories to the ui/assets/bootstrap directory
    ​​​​​​​


Elements of fontawesome

  • Go to the fontawesome website (Download part)
    https://fontawesome.com/download
  • Download font Awesome free for the web
    ​​​​​​​Download
    compiled CSS and JS files
  • The file we are interested in is fontawesome-free-6.5.2-web.zip
  • Unzip the fontawesome-free-6.5.2-web.zip file
  • Copy the CSS, JS and webfonts directories to the ui / assets / fontawesome directory

Noticed
Any installed files will not be used.
In this case, we can clean up and leave only the essentials.
For fontawesome we will only keep the files all.css , all.min.css and all.js and all.min.js
You will find the final result on the source code repository indicated at the end of the tutorial.


In the source code you will find the directory

  • ui (bootstrap 5 code)

Our first Bootstrap page

We are going to create our first page using the examples offered by bootstrap as inspiration.

We will use the examples page


Arbitrarily I give you the final result of an example page.
The different parts follow.

style body
  <style>
    body {
      padding-top: 3.5rem;
      font-family: "Roboto", sans-serif;
    }
  </style>
style header
  <!-- HEADER -->
  <style>
    .navbar.navbar-dark .navbar-nav .nav-item .nav-link {
      color: white;
      font-weight: 500;
      border-top: 1px solid #09238d;
      border-bottom: 1px solid #09238d;
    }

    .navbar.navbar-dark .navbar-nav .nav-item .nav-link:hover {
      color: yellow;
      border-top: 1px solid yellow;
      border-bottom: 1px solid yellow;
    }

    .nga-navbar {
      -webkit-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 11px 10px 0 rgba(0, 0, 0, 0.12);
      box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 11px 10px 0 rgba(0, 0, 0, 0.12);
      background-color: #09238d;
    }

    .nga-logo {
      font-weight: 700;
    }

    .nga-logo:hover {
      color: rgba(255, 255, 255, 0.75);
    }

    .nga-btn-navbar {
      color: #fff;
      background-color: #1976d2;
      border-color: #0d6efd;
    }

    .nga-btn-navbar:hover {
      color: white;
      background-color: #0b5ed7;
      border-color: #0a58ca;
    }
  </style>
style footer
  <!-- FOOTER -->
  <style>
    .nga-footer {
      background-color: #212121;
      color: white;
    }

    .nga-footer a {
      color: white;
      text-decoration: none
    }

    .nga-footer a:hover,
    .nga-footer a:focus {
      color: yellow;
      text-decoration: underline;
    }

    .nga-footer .hint {
      background-color: #1976d2;
    }

    .nga-footer .hint:hover {
      opacity: 0.8;
    }
  </style>
style home
  <!-- HOME -->
  <style>
    .nga-card {
      display: block;
      background-color: rgba(255, 255, 255, .8);
      box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24);
      border-radius: 2px;
      transition: all .2s ease-in-out;
      cursor: pointer;
    }

    .nga-card:hover {
      box-shadow: 0 10px 20px rgba(0, 0, 0, .19), 0 6px 6px rgba(0, 0, 0, .23);
    }
  </style>
html header
  <header class="navbar navbar-expand-md navbar-dark fixed-top nga-navbar">
    <nav class="container" aria-label="Main navigation">
      <a href="" class="navbar-brand" alt="Accueil" aria-label="Ganatan">
        <img src="./assets/params/images/logo/ganatan-logo.png" srcset="./assets/params/images/logo/ganatan-logo.png,
        ./assets/params/images/logo/ganatan-logo@2x.png 2x" width="25" height="25" alt="Ganatan Logo">
        <span class="nga-logo mx-1">ganatan</span>
      </a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse"
        aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarCollapse">
        <ul class="navbar-nav mx-auto">
          <li class="nav-item">
            <a class="nav-link" aria-current="page" href="">
              <i class="fas fa-home me-1"></i>Home</a>
          </li>
        </ul>
        <ul class="navbar-nav me-auto">
          <li class="nav-item">
            <a class="nav-link active" aria-current="page" href="">
              <i class="far fa-question-circle me-1"></i>About</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" aria-current="page" href="">
              <i class="fas fa-envelope me-1"></i>Contact</a>
          </li>
        </ul>
        <form class="d-flex">
          <button type="button" class="btn btn-sm nga-btn-navbar me-2"><i class="fas fa-user-plus me-2"></i>Sign
            up</button>
          <button type="button" class="btn btn-sm btn-outline-light me-2"><i
              class="fas fa-sign-in-alt me-2"></i>Login</button>
        </form>
      </div>
    </nav>
  </header>
html main
  <main>

    <div class="container py-5">
      <div class="row">
        <div class="col-12 col-sm-12 col-md-12 col-lg-3 col-xl-3 text-center mb-2">
          <h1 class="h5">
            <i class="fas fa-laptop fa-lg me-2 text-primary"></i>
            angular-starter
            <i class="fas fa-mobile-alt fa-lg ms-2 text-primary"></i>
          </h1>
        </div>
        <div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-danger mb-2">
          <h2 class="h5">
            Angular 16.2.4<i class="fab fa-angular fa-lg ms-2"></i>
          </h2>
        </div>
        <div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-primary mb-2">
          <h2 class="h5">
            Bootstrap 5.3.1<i class="fab fa-bootstrap fa-lg ms-2"></i>
          </h2>
        </div>
        <div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-success mb-2">
          <h2 class="h5">
            Font Awesome 6.4.2<i class="fab fa-font-awesome-flag fa-lg ms-2"></i>
          </h2>
        </div>
      </div>
      <hr>
      <div class="row mb-2">
        <div class="col-md-12 text-center mb-4">
          <h3 class="h5">Features<i class="fas fa-list ms-2"></i></h3>
        </div>
      </div>
      <div class="row pt-2">
        <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
          <div class="nga-card bg-light mb-3">
            <a routerLink="/bootstrap">
              <div class="card-header">
                <div class="row">
                  <div class="col-10 col-xl-10">
                    <h5 class="card-title">Bootstrap</h5>
                  </div>
                  <div class="col-2 col-xl-2">
                    <i class="fab fa-bootstrap fa-lg text-primary"></i>
                  </div>
                </div>
              </div>
              <div class="card-body">
                <p class="card-text">How to use Buttons, Alerts, Pagination, Tables, Collapses</p>
              </div>
            </a>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
          <div class="nga-card bg-light mb-3">
            <div class="card-header">
              <div class="row">
                <div class="col-10 col-xl-10">
                  <h5 class="card-title">Services</h5>
                </div>
                <div class="col-2 col-xl-2">
                  <i class="fas fa-handshake fa-lg text-primary"></i>
                </div>
              </div>
            </div>
            <div class="card-body">
              <p class="card-text">Use services to view a playlist and a youtube player</p>
            </div>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
          <div class="nga-card bg-light mb-3">
            <div class="card-header">
              <div class="row">
                <div class="col-10 col-xl-10">
                  <h5 class="card-title">Components</h5>
                </div>
                <div class="col-2 col-xl-2">
                  <i class="far fa-clone  fa-lg text-primary"></i>
                </div>
              </div>
            </div>
            <div class="card-body">
              <p class="card-text">Channel component with Input, Output and Event Emitter</p>
            </div>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
          <div class="nga-card bg-light mb-3">
            <div class="card-header">
              <div class="row">
                <div class="col-10 col-xl-10">
                  <h5 class="card-title">Reactive Forms</h5>
                </div>
                <div class="col-2 col-xl-2">
                  <i class="far fa-file-alt fa-lg text-primary"></i>
                </div>
              </div>
            </div>
            <div class="card-body">
              <p class="card-text">A model-driven approach to handling form inputs</p>
            </div>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
          <div class="nga-card bg-light mb-3">
            <div class="card-header">
              <div class="row">
                <div class="col-10 col-xl-10">
                  <h5 class="card-title">Template Driven Forms</h5>
                </div>
                <div class="col-2 col-xl-2">
                  <i class="far fa-file-alt fa-lg text-primary"></i>
                </div>
              </div>
            </div>
            <div class="card-body">
              <p class="card-text">Forms are the mainstay of business applications</p>
            </div>
          </div>
        </div>
      </div>
    </div>

  </main>

Bootstrap integration in Angular

Now let's move on to the logical part.
We are going to make this home page work in our base Angular project .

First of all we need to add the necessary libraries.
To do this, we use npm (node ​​package manager) the Nodes.js dependency manager

Pour bootstrap on suivra les conseils sur le site officiel.
https://v5.getbootstrap.com/docs/5.1/getting-started/download/

# Adding dependencies in package.json
npm install --save bootstrap
npm install --save @fortawesome/fontawesome-free

As we saw in the Getting Started with Angular tutorial we will modify the dependency version descriptors.

Concerning the dependencies and their version the npm documentation is as follows
https://docs.npmjs.com/files/package.json#dependencies

Which will give us the following result.

package.json
    "@fortawesome/fontawesome-free": "6.5.2",
    "bootstrap": "5.3.3",
    "rxjs": "7.8.1",
    "tslib": "2.6.2",
    "zone.js": "0.14.2"

Update

So let's reuse the elements of our prototype.
Copy all the params directory from our prototype into our angular application at src/assets

We are going to modify the angular.json file in order to call the files necessary for the operation of our html pages.

CSS formatting files

  • index.css (specific to our project via params)
  • all.min.css (specific to fontawesome via node_modules)
  • bootstrap.min.css (specific to bootstrap via node_modules)


JavaScript script files

angular.json
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/angular-starter",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "node_modules/@fortawesome/fontawesome-free/css/all.min.css",
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/assets/params/css/fonts.googleapis.min.css",
              "src/styles.css"
            ],
            "scripts": [
              "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
            ]
          },
src/style.css
body {
  padding-top: 3.5rem;
  font-family: "Roboto", sans-serif;
}

We will modify the following files which will contain the new interface

  • app.component.html
  • app.component.css
  • home.component.html
  • home.component.ts
  • home.component.css
  • ​​​​​​​home.component.spec.ts
  • environment.ts
  • environment.development.ts
  • app.component.spec.ts
  • app.component.ts
  • about.html
  • signin.css
  • contact.html
  • ​​​​​​​notfound.html

We will add the images used in the assets/params/images/logo directory

  • ganatan.png
src/app/app.component.html
<header class="navbar navbar-expand-md navbar-dark fixed-top nga-navbar">
  <nav class="container" aria-label="Main navigation">
    <a routerLink="/" class="navbar-brand" alt="Accueil" aria-label="Ganatan">
      <img src="./assets/params/images/logo/ganatan-logo.png" srcset="./assets/params/images/logo/ganatan-logo.png,
      ./assets/params/images/logo/ganatan-logo@2x.png 2x" width="25" height="25" alt="Logo Ganatan">
      <span class="nga-logo mx-1">ganatan</span>
    </a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse"
      aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarCollapse">
      <ul class="navbar-nav mx-auto">
        <li class="nav-item">
          <a class="nav-link" aria-current="page" routerLink="/">
            <i class="fas fa-home me-1"></i>Home</a>
        </li>
      </ul>
      <ul class="navbar-nav me-auto">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" routerLink="/about">
            <i class="far fa-question-circle me-1"></i>About</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" aria-current="page" routerLink="/contact">
            <i class="fas fa-envelope me-1"></i>Contact</a>
        </li>
      </ul>
      <form class="d-flex">
        <button type="button" class="btn btn-sm btn-primary me-2" routerLink="/signup"><i
            class="fas fa-user-plus me-2"></i>Sign up</button>
        <button type="button" class="btn btn-sm btn-outline-light me-2" routerLink="/login"><i
            class="fas fa-sign-in-alt me-2"></i>Login</button>
      </form>
    </div>
  </nav>
</header>

<main>
  <router-outlet></router-outlet>
</main>

<footer class="nga-footer">
  <div class="py-3 text-center" style="background-color: black;">
    <div class="container">
      <a href="{{ footerUrl }}">{{ footerLink }}</a>
    </div>
  </div>
</footer>
src/app/app.component.css
.navbar.navbar-dark .navbar-nav .nav-item .nav-link {
    color: white;
    font-weight: 500;
    border-top: 1px solid #09238d;
    border-bottom: 1px solid #09238d;
  }
  
  .navbar.navbar-dark .navbar-nav .nav-item .nav-link:hover {
    color: yellow;
    border-top: 1px solid yellow;
    border-bottom: 1px solid yellow;
  }
  
  .nga-navbar {
    -webkit-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 11px 10px 0 rgba(0, 0, 0, 0.12);
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 11px 10px 0 rgba(0, 0, 0, 0.12);
    background-color: #09238d;
  }
  
  .nga-navbar-logo {
    font-weight: 700;
  }
  
  .nga-navbar-logo:hover {
    color: rgba(255, 255, 255, 0.75);
  }
  
  .nga-logo {
    font-weight: 700;
  }
  
  .nga-logo:hover {
    color: rgba(255, 255, 255, 0.75);
  }
  
  .nga-footer {
    background-color: #212121;
    color: white;
  }
  
  .nga-footer a {
    color: white;
    text-decoration: none
  }
  
  .nga-footer a:hover,
  .nga-footer a:focus {
    color: yellow;
    text-decoration: underline;
  }
  
  .nga-footer .hint {
    background-color: #1976d2;
  }
  
  .nga-footer .hint:hover {
    opacity: 0.8;
  }
src/app/pages/general/home/home.component.html
<div class="container py-5">
    <div class="row">
      <div class="col-12 col-sm-12 col-md-12 col-lg-3 col-xl-3 text-center mb-2">
        <h1 class="h5">
          <i class="fas fa-laptop fa-lg me-2 text-primary"></i>
          {{ name }}
          <i class="fas fa-mobile-alt fa-lg ms-2 text-primary"></i>
        </h1>
      </div>
      <div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-danger mb-2">
        <h2 class="h5">
          {{ version }}<i class="fab fa-angular fa-lg ms-2"></i>
        </h2>
      </div>
      <div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-primary mb-2">
        <h2 class="h5">
          {{ bootstrap }}<i class="fab fa-bootstrap fa-lg ms-2"></i>
        </h2>
      </div>
      <div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 text-center text-success mb-2">
        <h2 class="h5">
          {{ fontawesome }}<i class="fab fa-font-awesome-flag fa-lg ms-2"></i>
        </h2>
      </div>
    </div>
    <hr>
    <div class="row mb-2">
      <div class="col-md-12 text-center mb-4">
        <h3 class="h5">Features<i class="fas fa-list ms-2"></i></h3>
      </div>
    </div>
    <div class="row pt-2">
      <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
        <div class="card nga-card bg-light mb-3">
          <a routerLink="/bootstrap">
            <div class="card-header">
              <div class="row">
                <div class="col-10 col-xl-10">
                  <h4 class="card-title h5">Bootstrap</h4>
                </div>
                <div class="col-2 col-xl-2">
                  <i class="fab fa-bootstrap fa-lg text-primary"></i>
                </div>
              </div>
            </div>
            <div class="card-body">
              <p class="card-text">How to use Buttons, Alerts, Pagination, Tables, Collapses</p>
            </div>
          </a>
        </div>
      </div>
      <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
        <div class="card nga-card bg-light mb-3">
          <div class="card-header">
            <div class="row">
              <div class="col-10 col-xl-10">
                <h4 class="card-title h5">Services</h4>
              </div>
              <div class="col-2 col-xl-2">
                <i class="fas fa-handshake fa-lg text-primary"></i>
              </div>
            </div>
          </div>
          <div class="card-body">
            <p class="card-text">Use services to view a playlist and a youtube player</p>
          </div>
        </div>
      </div>
      <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
        <div class="card nga-card bg-light mb-3">
          <div class="card-header">
            <div class="row">
              <div class="col-10 col-xl-10">
                <h4 class="card-title h5">Components</h4>
              </div>
              <div class="col-2 col-xl-2">
                <i class="far fa-clone  fa-lg text-primary"></i>
              </div>
            </div>
          </div>
          <div class="card-body">
            <p class="card-text">Channel component with Input, Output and Event Emitter</p>
          </div>
        </div>
      </div>
      <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
        <div class="card nga-card bg-light mb-3">
          <div class="card-header">
            <div class="row">
              <div class="col-10 col-xl-10">
                <h4 class="card-title h5">Reactive Forms</h4>
              </div>
              <div class="col-2 col-xl-2">
                <i class="far fa-file-alt fa-lg text-primary"></i>
              </div>
            </div>
          </div>
          <div class="card-body">
            <p class="card-text">A model-driven approach to handling form inputs</p>
          </div>
        </div>
      </div>
      <div class="col-12 col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-2">
        <div class="card nga-card bg-light mb-3">
          <div class="card-header">
            <div class="row">
              <div class="col-10 col-xl-10">
                <h4 class="card-title h5">Template Driven Forms</h4>
              </div>
              <div class="col-2 col-xl-2">
                <i class="far fa-file-alt fa-lg text-primary"></i>
              </div>
            </div>
          </div>
          <div class="card-body">
            <p class="card-text">Forms are the mainstay of business applications</p>
          </div>
        </div>
      </div>
    </div>
  </div>
src/app/pages/general/home/home.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink, RouterOutlet } from '@angular/router';

import { environment } from '../../../../environments/environment';

@Component({
  selector: 'app-home',
  standalone: true,
  imports: [CommonModule, RouterLink, RouterOutlet],
  templateUrl: './home.component.html',
  styleUrl: './home.component.css'
})
export class HomeComponent {
  name = environment.application.name;
  version = environment.application.version;
  bootstrap = environment.application.bootstrap;
  fontawesome = environment.application.fontawesome;
}
src/app/pages/general/home/home.component.css
.nga-card {
    display: block;
    background-color: rgba(255, 255, 255, .8);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24);
    border-radius: 2px;
    transition: all .2s ease-in-out;
    cursor: pointer;
  }
  
  .nga-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 20px rgba(0, 0, 0, .19), 0 6px 6px rgba(0, 0, 0, .23);
  }
  
  .nga-card a {
    color: black;
    text-decoration: none;
  }
  
  .nga-card a:hover {
    color: #0d6efd;
    text-decoration: none;
  }
  
src/app/pages/general/home/home.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { HomeComponent } from './home.component';
import { RouterTestingModule } from '@angular/router/testing';

describe('HomeComponent', () => {
  let component: HomeComponent;
  let fixture: ComponentFixture<HomeComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [HomeComponent, RouterTestingModule]
    })
      .compileComponents();

    fixture = TestBed.createComponent(HomeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
src/environments/environments.ts
export const environment = {
    application:
    {
      name: 'angular-bootstrap',
      version: 'Angular 18.0.2',
      bootstrap: 'Bootstrap 5.3.3',
      fontawesome: 'Font Awesome 6.5.2',
    }
  };
src/environments/environment.development.ts
export const environment = {
    application:
    {
      name: 'angular-bootstrap',
      version: 'Angular 18.0.2',
      bootstrap: 'Bootstrap 5.3.3',
      fontawesome: 'Font Awesome 6.5.2',
    }
  };
src/app/app.component.spec.ts
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { RouterTestingModule } from '@angular/router/testing';

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });

  it(`should have as title 'angular-starter'`, () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app.title).toEqual('angular-starter');
  });

});
src/app/pages/general/about/about.html
<div class="row">
  <div class="col-12 col-sm-12 col-md-3 col-lg-3 col-xl-3">
    <p class="text-center">about works!</p>
    <ul>
      <li><a routerLink="/about/experience">experience</a></li>
      <li><a routerLink="/about/skill">skill</a></li>
    </ul>
  </div>
  <div class="col-12 col-sm-12 col-md-9 col-lg-9 col-xl-9">
    <router-outlet></router-outlet>
  </div>
</div>
src/app/pages/general/contact/contact.html
<div class="row">
  <div class="col-12 col-sm-12 col-md-3 col-lg-3 col-xl-3">
    <p class="text-center">contact works!</p>
    <ul>
      <li><a routerLink="/contact/mailing">Mailing</a></li>
      <li><a routerLink="/contact/map">Map</a></li>
      <li><a routerLink="/contact/website">Website</a></li>
    </ul>
  </div>
  <div class="col-12 col-sm-12 col-md-9 col-lg-9 col-xl-9">
    <router-outlet></router-outlet>
  </div>
</div>
src/app/pages/general/signup/signup.html
<p class="text-center">signup works!</p>
src/app/pages/general/not-found/not-found.html
<p class="text-center">not-found works!</p>

Bootstrap Components

The final project includes a module for testing Bootstrap components.

As the code is too long, I do not indicate it in this tutorial.
However, the full source is available on Github.


It is added via routing in the following files

app.routes.ts
  {
    path: 'bootstrap',
    loadChildren: () => import('./pages/application/example-bootstrap/tutorial.module')
      .then(mod => mod.TutorialModule)
  },

Tests

Il ne reste plus qu'à tester les différents scripts Angular.

# Développement
npm run start
http://localhost:4200/

# Tests
npm run test

# Compilation
npm run build

Compilation errors

The compilation will generate an error.
The reason our CSS code exceeds a certain size recommended in the parameters.

The parameters are contained in the angular.json file.
These parameters are restrictive in my opinion, it is enough to modify them to remove the warning

For the initial bundle the maximumWarning parameter is by default at 500kb
We will use maximumWarning at 1mb

For the other components the maximumWarning parameter is by default at 2kb
We will use maximumWarning at 4kb

"production": {
  "budgets": [
    {
      "type": "initial",
      "maximumWarning": "1mb",
      "maximumError": "1mb"
    },
    {
      "type": "anyComponentStyle",
      "maximumWarning": "4kb",
      "maximumError": "4kb"
    }
  ],

Source Code

By following each of the tips I've given you in this guide, you end up with an Angular source code.

The source code obtained at the end of this tutorial is available on github
https://github.com/ganatan/angular-react-bootstrap

If you like the source code a star on github and let's go.​​​​​​​

A star and a happy warrior ?


The next step will allow us to improve our structure.
The full tutorial is at the following address

The following steps will get you a prototype application.

​​​​​​​​​​​​​
This last step provides an example of an application

The source code of this final application is available on GitHub
https://github.com/ganatan/angular-app