Update: Using Angular TitleStrategy
Tags: angular, typescript, webdev, seo
Published: 2022-09-22 13:55:22

Angular 14 brought forward a new service provided in root: [TitleStrategy](https://angular.io/guide/router#setting-the-page-title), which basically does what we did before in [SEO in Angular: Static page titles using route data](https://garage.sekrab.com/posts/seo-in-angular-with-ssr-part-i). 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:

```ts
// 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](https://stackblitz.com/edit/angular-seo-service), 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:

```ts
// 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](https://github.com/angular/angular/blob/main/packages/router/src/page_title_strategy.ts#L46), the `buildTitle` gets the deepest route title, as expected.

```ts
// /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:

```ts
// 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](https://garage.sekrab.com/posts/alternative-way-to-localize-in-angular)

Happy coding. 🙂

> Want to be updated of new articles on **Sekrab Garage**: Subscribe to [**Sekrab Parts**](http://parts.sekrab.com/) newsletter

### RESOURCES

-   [Angular TitleStrategy](https://angular.io/guide/router#setting-the-page-title)
-   [StackBlitz project](https://stackblitz.com/edit/angular-seo-service-14)

### RELATED POSTS
- [Alternative way to localize in Angular](https://garage.sekrab.com/posts/alternative-way-to-localize-in-angular)