Learn how to set dynamic page title based on Route in Angular using Title Service in Angular. We learned how to is set the page title using the Title service in Angular. Setting the title in each component is somewhat a tedious task. You may miss some of the components. The simpler solution is to define the title along with the routes and use it to update the title. To achieve that, we will make use of Angular route data Property.
Table of Contents
Example App
Create a new angular app.
Add five Angular Components. HomeComponent
, OneComponent
, TwoComponent
, ThreeComponent
& TwoAComponent
1 2 3 4 5 6 7 8 9 10 11 12 | import { Component} from '@angular/core'; @Component({ template: `<h1>Home Component</h1> ` }) export class HomeComponent { } |
1 2 3 4 5 6 7 8 9 10 | import { Component } from '@angular/core'; @Component({ template: `<h1>One Component</h1>` }) export class OneComponent{ } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import { Component} from '@angular/core'; @Component({ template: `<h1>Two Component</h1> <router-outlet></router-outlet> ` }) export class TwoComponent { } |
1 2 3 4 5 6 7 8 9 10 11 | import { Component} from '@angular/core'; @Component({ template: `<h1>Three Component</h1>` }) export class ThreeComponent { } |
1 2 3 4 5 6 7 8 9 10 11 12 | import { Component } from '@angular/core'; @Component({ template: `<h1>Two A Component</h1>` }) export class TwoAComponent { } |
Import Title Service
Open the app.module.ts
and import the Title Service form the @angular/platform-browser
as shown below. Also, use the Angular Providers metadata to register the Title service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import { BrowserModule, Title } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { OneComponent } from './one.component'; import { TwoComponent } from './two-component'; import { ThreeComponent } from './three.component'; import { TwoAComponent } from './two-a.component'; import { HomeComponent } from './home.component'; @NgModule({ declarations: [ AppComponent,OneComponent,TwoComponent,ThreeComponent,TwoAComponent, HomeComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [Title], bootstrap: [AppComponent] }) export class AppModule { } |
Define the title in Routes
Open the app-routing.module.ts
and the routes as shown below. Add the title property in route data. Route data can be used to pass the static data or dynamic data to routed components.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { OneComponent } from './one.component'; import { TwoComponent } from './two-component'; import { ThreeComponent } from './three.component'; import { TwoAComponent } from './two-a.component'; import { HomeComponent } from './home.component'; const routes: Routes = [ {path:'',component:HomeComponent, data : {title:'Title for Home Component'}}, {path: 'one', component:OneComponent, data :{ title:'Title for One Component'}}, {path: 'two', component:TwoComponent, data :{ title:'Title for Two Component'}, children: [ {path:'a',component:TwoAComponent, data : {title:'title for two a component'}} ] }, {path: 'three', component:ThreeComponent, data :{ title:'Title for three Component'}}, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } |
The trick to changing the title is to know when the route changes. This we can do by listening to the NavigationEnd
event.
We also need to listen to every route change event in the app. The app.component.ts
is the topmost component in our app. It loads when the app starts. It lives as long as the app lives. Hence the best place to listen to the route changes is in the app.component.ts
The following is the code of the app.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import { Component } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { Router, NavigationEnd, ActivatedRoute } from '@angular/router'; import { filter, map } from 'rxjs/operators'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { constructor(private router: Router, private activatedRoute: ActivatedRoute, private titleService: Title) { } ngOnInit() { this.router.events.pipe( filter(event => event instanceof NavigationEnd), ) .subscribe(() => { var rt = this.getChild(this.activatedRoute) rt.data.subscribe(data => { console.log(data); this.titleService.setTitle(data.title)}) }) } getChild(activatedRoute: ActivatedRoute) { if (activatedRoute.firstChild) { return this.getChild(activatedRoute.firstChild); } else { return activatedRoute; } } } |
First, we inject Router
, ActivatedRoute
& Title
services in our constructor
In ngOnInit, we listen to the router events. We use the filter
operator to listen to only to the NavigationEnd
event.
We need to find the ActivateRoute
of the last loaded component. Hence, we use the firstChild
property of the ActivatedRoute
to recursively traverse through the Router Tree to get the bottom-most Activate Route. We use the getChild
method to do that.
Once, we get the ActivateRoute
of the last loaded component, all we need to do is subscribe
to the Route, data to get the title stored in the route data.
Finally, use the setTitle
of the Title service to set the Title tag
Summary
We learned how to set the dynamic page title by using Angular Routes.
Helped. Thank you. The attribute “data” was the key and as value I could use the pattern:
“FILENAME.KEY.SUBKEY.VALUE”, e.g. “global.mymod.users.title”: “Benutzer”.
Very very good.
The example is good and easy to understand.
I have some similar scenario like I have department component, employee component and roles component, in this component i will display the related details. Like whenever i navigate to employee component my browser title should display information like “Employee Name: Employee Number”, if i navigate to dpeartment component browser title should display information like “Department Name: Department Number”
Can you please suggest how to achieve this in generic way instead of setting title in each component.
Thanks & Regards
Amruta W
That’s tricky to achieve because the employee name is available only after the route change event. Setting it in the component seems to be the best & simple solution.
You mean to say is I have to set in each component?