How to change page title with routing in Angular application?

You have a TitleService in Angular 5. Inject it in your component's constructor, and use the setTitle() method.

import {Title} from "@angular/platform-browser";

....

constructor(private titleService:Title) {
  this.titleService.setTitle("Some title");
}

Here are the docs from Angular: https://angular.io/guide/set-document-title


Here is tested way to set page title on Angular 8 but you can use it on Angular 5 as well. Once you set this you have to just set title on route file and all will set automatically.

import { Component } from '@angular/core';
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
import { Title } from '@angular/platform-browser';
import { filter, map } from "rxjs/operators";

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html'
})
export class AppComponent {

    constructor (private router: Router, private activatedRoute:    ActivatedRoute, private titleService: Title) {
        this.router.events.pipe(
            filter(event => event instanceof NavigationEnd),
            map(() => {
                let child = this.activatedRoute.firstChild;
                while (child) {
                    if (child.firstChild) {
                        child = child.firstChild;
                    } else if (child.snapshot.data &&    child.snapshot.data['title']) {
                        return child.snapshot.data['title'];
                    } else {
                        return null;
                    }
                }
                return null;
            })
        ).subscribe( (data: any) => {
            if (data) {
                this.titleService.setTitle(data + ' - Website Name');
            }
        });
    }

}

And on route file you can do something like this:

const routes: Routes = [
    {
        path: 'dashboard',
        component: DefaultDashboardComponent,
        data: {
            title: 'Dashboard'
        }
    }
];

In Angular v14, there is a built-in strategy service for collecting the title from the route based on the primary router outlet, and setting the browser's page title.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AboutComponent } from './about.component';
import { HomeComponent } from './home.component';

const routes: Routes = [
  {
    path: 'home',
    component: HomeComponent,
    title: "'My App - Home' // <-- Page title"
  },
  {
    path: 'about',
    component: AboutComponent,
    title: "'My App - About Me'  // <-- Page title"
  }
];

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

See here


Here's a non-recursive solution that also fixes the replication of titles in case of path-less or component-less nested routes.

Make sure to add Angular's Title service to your application: https://angular.io/guide/set-document-title.

Then in your app.component.ts

import { Component, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { NavigationEnd, Router } from '@angular/router';
import { filter } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  constructor(
    private readonly router: Router,
    private readonly titleService: Title
  ) { }

  ngOnInit() {
    this.router.events.pipe(
      filter((event) => event instanceof NavigationEnd)
    ).subscribe(() => {
      this.titleService.setTitle(this.getNestedRouteTitles().join(' | '));
    });
  }

  getNestedRouteTitles(): string[] {
    let currentRoute = this.router.routerState.root.firstChild;
    const titles: string[] = [];

    while (currentRoute) {
      if (currentRoute.snapshot.routeConfig.data?.title) {
        titles.push(currentRoute.snapshot.routeConfig.data.title);
      }

      currentRoute = currentRoute.firstChild;
    }

    return titles;
  }

  getLastRouteTitle(): string {
    let currentRoute = this.router.routerState.root.firstChild;

    while (currentRoute.firstChild) {
      currentRoute = currentRoute.firstChild;
    }

    return currentRoute.snapshot.data?.title;
  }
}

Accessing the specific routeConfig.data prevents the repetition of the inherited title attribute.

And in main-routing.module.ts or any of your other routing files:

const routes: Routes = [
  {
    path: '',
    component: MainComponent,
    data: { title: 'MyApplication' },
    children: [
      {
        path: '',
        canActivateChild: [AuthGuard],
        children: [
          {
            path: 'dashboard',
            loadChildren: () => import('../dashboard/dashboard.module').then(m => m.DashboardModule),
            data: { title: 'Dashboard' }
          },
          {
            path: 'settings',
            loadChildren: () => import('../settings/settings.module').then(m => m.SettingsModule),
            data: { title: 'Settings' }
          }
        ]
      }
    ]
  }
];