Dynamically Set Page Title in Angular App
Tags: angular, javascript, webdev
Published: 2021-04-11 22:57:00

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!

## 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!

```javascript
{ 
  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.

```javascript
{ 
  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](https://angular.io/guide/router) to listen for navigation events, the [ActivatedRoute](https://angular.io/api/router/ActivatedRoute) to know what page the user is currently on, and the [NavigationEnd](https://angular.io/api/router/NavigationEnd) event. Let’s import those from the router package.

```javascript
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
```

We need the [Title](https://angular.io/api/platform-browser/Title) service, which provides us the ability to set the page title. You can import the Title service from the platform browser package.

```javascript
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](https://www.learnrxjs.io/learn-rxjs/operators/filtering/filter) operator will help us filter events related to NavigationEnd only. The [map](https://www.learnrxjs.io/learn-rxjs/operators/transformation/map) operator will allow us to return the data the way we need.

```javascript
import { filter, map } from 'rxjs/operators';
```

In our app constructor, pass in the following:

```javascript
constructor(
  private activatedRoute: ActivatedRoute,
  private title: Title,
  private router: Router
)
```

Now let’s create a function called **setPageTitle**.

```javascript
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.

```javascript
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.

```javascript
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.

```javascript
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.

```javascript
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.

```javascript
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.

```javascript
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));
}
```

---
**Visit our website at [https://nightwolf.dev](https://nightwolf.dev) and follow us on [Facebook](https://www.facebook.com/NightWolfDevelopment) and [Twitter](https://twitter.com/nightwolfdev)!**