Managing Page Title in Angular

page title angular

Managing page title in Angular is quite straightforward by using the Title service provided by Angular. It’s as simple as calling the setTitle function with the new title.

Following is an code excerpt from Angular docs

public constructor(private titleService: Title ) { }
public setTitle( newTitle: string) {
  this.titleService.setTitle( newTitle );
}

This is fine for setting the page title from a single page, but it can be redundant to add this to every component from where you want to change the title.

To make it easier, we can use the router events and have a centralized place to make the title changes.

We will use the app.component.ts to manage the title. You can use any other component you want, but need to make sure that component instance should always be present throughout the life-cycle of the application

First inject the Title service to the constructor. We also need to inject the Router service to be able to listen to it’s events.

export class AppComponent implements OnInit {
    title = 'My App';

    constructor(private router: Router, private titleService: Title) {
        this.titleService.setTitle(this.title);
    }
}

To get the title we want to show, we can use the static data attribute that is available on the Route we define.

const routes: Routes = [
    { path: '', component: UserListComponent, data: { title: 'User List' } },
    { path: ':id', component: UserEditComponent, data: { title: 'Add/Edit' } }
];
// title can be replaced with any name and the same can be used while creating the title

This can be replicated for any Route we define. We also can omit the attribute, and in that case, we won’t add that part to the title generator.

Now we need to listen to the Router events and look for the ActivationEnd event, because on this life-cycle event only, we will find the data that we have associated to the Route.

ngOnInit() {
    this.router.events.pipe(
      filter(event => event instanceof ActivationEnd)
    ).subscribe((event: ActivationEnd) => this.generateTitle(event));
}
generateTitle(event: ActivationEnd) {
    const data = [this.title];
    this.buildRouteTitle(data, event.snapshot.firstChild);
    this.titleService.setTitle(data.join(' | '));
}

buildRouteTitle(arr: Array<string>, route: ActivatedRouteSnapshot) {
    if (route) {
      if (route.data.title) {
        arr.push(route.data.title);
        // arr.unshift(route.data.title); // If required to show the child title first
      }
      if (route.firstChild) {
        return this.buildRouteTitle(arr, route.firstChild);
      }
    }
    return arr;
}

After creating this structure, the resultant user-list page title would look like:
My App | User List

If you have multiple level of view and each have their title attribute, they would show up in that manner.
My App | Parent Route Title | Child Route Title

This is what I’m using to change the page title for now. Any enhancements to the code is highly welcome.

If anyone knows of any better way for managing page title in Angular, please let us know.

Learn more on Angular here.

Leave a Reply