Sekrab Garage

SEO in Angular

Update: Using Angular TitleStrategy

AngularDesign September 22, 22
Series:

SEO Service

In this three-part article, we are putting together a service to handle SEO requirements in an Angular application.
  1. 7 months ago
    SEO in Angular with SSR - Part I
  2. 6 months ago
    SEO in Angular with SSR - Part II
  3. 6 months ago
    SEO in Angular with SSR - Part III
  4. 15 days ago
    Update: Using Angular TitleStrategy

Angular 14 brought forward a new service provided in root: TitleStrategy, which basically does what we did before in SEO in Angular: Static page titles using route data. Now we can set the title as a direct property of the route. So let’s dig in and see how we can create our service spin off.

Updating SEO service

If we do absolutely nothing except set the title attribute in any of our routes like this:

// example route
const routes: Routes = [
   {
    path: 'details',
    component: ContentDetailsComponent,
    title: 'Details'
	}
];

Building and browsing to the route immediately takes over the page title. This is not what we want, we want to control it. That’s when we need to create an override. First, a revisit to our SEO project in StackBlitz, then a clean up of the code that was responsible for doing something similar.

In root app.component, we had an event subscriber that updated the title whenever a routing event occurred:

// root app.component adaptation
export class AppComponent {
  constructor(
    //...
  ) {
		// this is no longer needed since the TitleStrategy service 
		// already catches such events
    /* this.router.events
      .pipe(filter((e) => e instanceof NavigationEnd))
      .subscribe((event) => {
        let route = this.activatedRoute.snapshot;
        while (route.firstChild) {
          route = route.firstChild;
        }
        this.seoService.setPage((<any>route.data)?.title);
      });
	*/
  }
}

Next let’s create a new service that extends the TitleStrategy. Looking at the source code, the buildTitle gets the deepest route title, as expected.

// /services/title.service.ts
@Injectable({ providedIn: 'root' })
export class AppTitleStrategy extends TitleStrategy {
  constructor(private seoService: SeoService) {
    super();
  }
	// override updateTitle which is similar to catching NavigationEnd
  override updateTitle(routerState: RouterStateSnapshot) {
		// this retrieves the title value of the deepest child in the route
    const title = this.buildTitle(routerState);

		// now set the title using Title service
		// but we are going to use our previously created service: SeoService
		this.seoService.setPage(title);
  }
}

To put it to use, we need to overwrite it in the providers array at root level, or in the root routing module to keep things organized:

// routing.module.ts
NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  // new: title strategy here
  providers: [{ provide: TitleStrategy, useClass: AppTitleStrategy }],
})
export class AppRoutingModule {}

You might want to look at how we used similar Resources technique in Twisting Angular Localization

Happy coding. 🙂

Want to be updated of new articles on Sekrab Garage: Subscribe to Sekrab Parts newsletter
  1. 7 months ago
    SEO in Angular with SSR - Part I
  2. 6 months ago
    SEO in Angular with SSR - Part II
  3. 6 months ago
    SEO in Angular with SSR - Part III
  4. 15 days ago
    Update: Using Angular TitleStrategy