Create multiple layouts for different pages in Angular

Angular is open-source web application framework written in Typescript. Angular is used for single page web application where a common layout uses for all HTML views. So all HTML views use common layout.

In real life experience, a web application always have multiple common layouts. For example, Front user layouts, admin panel layout, login, register etc. These all views need different layouts than single common layouts.

In this article, we will use different layout for login page while front side common views uses common layout. So lets start it.

First of all create a fresh Angular project using ng new application command. If you want to learn how to create new Angular project, check this article.

AppRoutingModule

You have probably added AppRoutingModule module in the project when creating Angular project. If you have not added AppRoutingModule module in the application, add routing module with below command: It will create app-routing.ts file in the src/app directory.

ng generate module app-routing --flat --module=app

index.html and app.component.ts

Change in your main html files.

index.html file is main file which serve root tag in it. We will use different layouts for all views. So remove the code and only keep the <app-root> tag.

<base href="/">
<app-root></app-root>

In app.component.html file, also remove default code and add add <router-outlet> tag. This tag will render the components html code according to url.

<router-outlet></router-outlet>

LoginComponent

In this step, we will add login component and view in the project. So create login component using below ng command.

ng generate component login

This will add login folder with component and html file. Add login page HTML page in login/login.component.html file.

<!doctype html>
<html lang="en">
  <head>
    <title>Signin</title> 
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body class="text-center">
    <main class="form-signin">
      <form>
        <h1 class="h3 mb-3 fw-normal">Signin</h1>
        <div class="form-floating">
          <input type="email" class="form-control" id="floatingInput" placeholder="[email protected]">
          <label for="floatingInput">Email</label>
        </div>
        <div class="form-floating">
          <input type="password" class="form-control" id="floatingPassword" placeholder="Password">
          <label for="floatingPassword">Password</label>
        </div>
        <div class="mb-3">
        </div>
        <button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
        <p class="mt-5 mb-3 text-muted">&copy; 2021</p>
      </form>
    </main>
  </body>
</html>

Add css code in login/login.component.css file.

html,
body {
  height: 100%;
}

body {
  display: flex;
  align-items: center;
  padding-top: 40px;
  padding-bottom: 40px;
  background-color: #f5f5f5;
}

.form-signin {
  width: 100%;
  max-width: 330px;
  padding: 15px;
  margin: auto;
}

.form-signin .checkbox {
  font-weight: 400;
}

.form-signin .form-floating:focus-within {
  z-index: 2;
}

.form-signin input[type="email"] {
  margin-bottom: -1px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.form-signin input[type="password"] {
  margin-bottom: 10px;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
.bd-placeholder-img {
    font-size: 1.125rem;
    text-anchor: middle;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
}
@media (min-width: 768px) {
    .bd-placeholder-img-lg {
      font-size: 3.5rem;
    }
}

Add new route for login in app-routing.module.ts file. All routes are added in routes constant which are exported to main module app.module.ts file. You will also need to import LoginComponent on the top of file.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { LoginComponent } from './login/login.component';

const routes: Routes = [
  // login route
  { path: 'login', component: LoginComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Now build and run the Angular application with command. It will open the application main link http://localhost:4200 in the default browser.

ng serve --open

Change link http://localhost:4200/login and you can see login HTML page rendered on the link.

AppLayoutComponent

In this step, we will create new component for common layout. We will create children routes for all common pages which will use this common layout. Run the following command which will create a AppLayoutComponent component.

ng generate component app-layout

Now add your common layout HTML code in app-layout/app-layout.component.html file. <router-outlet> tag in this file will render all children routes HTML code.

<!doctype html>
<html lang="en" class="h-100">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
    <meta name="generator" content="Hugo 0.84.0">
    <title>Dashboard</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body class="d-flex flex-column h-100">
    <header>
      <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
        <div class="container-fluid">
          <a class="navbar-brand" routerLink="/" >Logo</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 me-auto mb-2 mb-md-0">
              <li class="nav-item">
                <a class="nav-link active" aria-current="page" routerLink="/">Home</a>
              </li>
              <li class="nav-item">
                <a class="nav-link active" aria-current="page" routerLink="/contact-us">Contact us</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" routerLink="/login">Login</a>
              </li>
            </ul>
          </div>
        </div>
      </nav>
    </header>
    <main class="flex-shrink-0">
      <div class="container">
        <router-outlet></router-outlet>
      </div>
    </main>
    <footer class="footer mt-auto py-3 bg-light">
      <div class="container">
        <span class="text-muted">&copy; 2021</span>
      </div>
    </footer>
  </body>
</html>

You can add common CSS in app-layout/app-layout.component.css file.

.bd-placeholder-img {
  font-size: 1.125rem;
  text-anchor: middle;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

@media (min-width: 768px) {
  .bd-placeholder-img-lg {
    font-size: 3.5rem;
  }
}
main > .container {
  padding: 60px 15px 0;
}

Note that in Angular links are defined with routerLink attribute instead of href attribute. We have added three links in the navigation bar. We have already created login route. Now we will add two more routes and create component for it. So let's start by creating home component.

HomeComponent and ContactUsComponent

ng generate component home
ng generate component contact-us

In the home component, add HTML code in home/home.component.ts file.

<h1 class="mt-5">Hello world</h1>
<p class="lead">This is homepage layout</p>

In the contact-us component, add contact us form in contact-us/contact-us.component.ts file.

<h1 class="mt-5">Contact us page</h1>
<p class="lead">Drop the message and we will contact you.</p>
<div class="row g-5">
  <div class="col-md-7 col-lg-8">
    <h4 class="mb-3">Billing address</h4>
    <form class="needs-validation" novalidate="">
      <div class="row mb-3">
        <div class="col-sm-6">
          <label for="firstName" class="form-label">First name</label>
          <input type="text" class="form-control" id="firstName" placeholder="" value="" required="">
        </div>
        <div class="col-sm-6">
          <label for="lastName" class="form-label">Last name</label>
          <input type="text" class="form-control" id="lastName" placeholder="" value="" required="">
        </div>
        <div class="col-12">
          <label for="message" class="form-label">Your message</label>
          <textarea class="form-control" id="message"></textarea>
        </div>
      </div>
      <button class="btn btn-primary" type="submit">Submit</button>
    </form>
  </div>
</div>

Update app-routing.module.ts file by adding two new routes with children routes.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { LoginComponent } from './login/login.component';
import { AppLayoutComponent } from './app-layout/app-layout.component';
import { HomeComponent } from './home/home.component';
import { ContactUsComponent } from './contact-us/contact-us.component';

const routes: Routes = [

  // basic routes
  { 
    path: '',
    component: AppLayoutComponent, 
    children: [
      { path: '', component: HomeComponent },
      { path: 'contact-us', component: ContactUsComponent }
    ]
  },
  // login route
  { path: 'login', component: LoginComponent },
  // redirect to home
  { path: '**', redirectTo: '' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Now in your browser, go to project root url http://localhost:4200. You can see navigation bar with links. You can go through login or contact us page by this link.

Tags: