Dynamically Set Page Title in Angular App
April 11, 2021 • Angular • Published By Josh • 4 minute read
The title tag is used to display the HTML page title in the browser’s title bar. It is a required tag and important for search engine optimization. An Angular application is considered a single page application (SPA). If there’s only one page generated, how do you display different titles for each of your pages? Let’s learn how!
Table of Contents
Angular 14 Update
As of Angular version 14, there is now a dedicated title property! You no longer need to listen to route changes and apply the title like the rest of this article explains. Just add the title property to your route!
{
path: 'about',
component: AboutComponent,
title: 'About'
}
Route Data
A typical Angular route will define the following:
- path – the url of the page
- component – the component to load when a user visits the page
There’s nothing stopping us from adding additional information to each route. For example, we could include the page title! Let’s create a property called data, which will hold any other information we want about each route. Create a property called title in the data object.
{
path: 'about',
component: AboutComponent,
data: {
title: 'About'
}
}
Router Events
As a user navigates around the Angular application, the router emits events. We can listen to these events, specifically the one called NavigationEnd, which is when the navigation ends, and capture the route data that holds our page title.
We need the Router to listen for navigation events, the ActivatedRoute to know what page the user is currently on, and the NavigationEnd event. Let’s import those from the router package.
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
We need the Title service, which provides us the ability to set the page title. You can import the Title service from the platform browser package.
import { Title } from '@angular/platform-browser';
When we’re listening to the router events, we’ll need a couple RxJS operators to help us out. The filter operator will help us filter events related to NavigationEnd only. The map operator will allow us to return the data the way we need.
import { filter, map } from 'rxjs/operators';
In our app constructor, pass in the following:
constructor(
private activatedRoute: ActivatedRoute,
private title: Title,
private router: Router
)
Now let’s create a function called setPageTitle.
setPageTitle(): void {
}
Create a variable called defaultPageTitle and set it to whatever you want the title to be if the route has no title defined.
const defaultPageTitle = 'Default Page Title';
We want to subscribe to the router events, eventually passing in the title to the setTitle function, which will set the page title.
this.router.events.pipe(
).subscribe((title: string) => this.title.setTitle(title));
Because we’re only interested in the NavigationEnd event, we need to filter what’s coming through the pipe. Let’s add the filter operator and limit it to the instance of NavigationEnd.
filter(event => event instanceof NavigationEnd)
Now add the map operator, which we’ll use to return the title. We need to figure out if this is a single route or if there are child routes. If there are no child routes, return the active route’s title or the default page title if the active route’s title is not defined. If a child route exists, we need to loop through all child routes until you find the last child. Then we can return the child route’s title or the default page title if the child route’s title is not defined.
map(() => {
let child = this.activatedRoute.firstChild;
if (!child) {
return this.activatedRoute.snapshot.data.title || defaultPageTitle;
}
while (child.firstChild) {
child = child.firstChild;
}
if (child.snapshot.data.title) {
return child.snapshot.data.title;
}
})
The setPageTitle function is complete. All that’s left to do is call it when the app component is initialized.
ngOnInit(): void {
this.setPageTitle();
}
Navigate around the application and the browser should display the respective page title!
Here’s the complete code for the setPageTitle function.
private setPageTitle(): void {
const defaultPageTitle = 'Default Page Title';
this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => {
let child = this.activatedRoute.firstChild;
if (!child) {
return this.activatedRoute.snapshot.data.title || defaultPageTitle;
}
while (child.firstChild) {
child = child.firstChild;
}
if (child.snapshot.data.title) {
return child.snapshot.data.title || defaultPageTitle;
}
})
).subscribe((title: string) => this.title.setTitle(title));
}