Dynamically add meta description based on route in Angular
First create a SEOService or Something like below:
import {Injectable} from '@angular/core'; import { Meta, Title } from '@angular/platform-browser';@Injectable({ provideIn: 'root' // Add this to ensure your SEO service will be app-wide available})export class SEOService { constructor(private title: Title, private meta: Meta) { } updateTitle(title: string) { this.title.setTitle(title); } updateOgUrl(url: string) { this.meta.updateTag({ name: 'og:url', content: url }) } updateDescription(desc: string) { this.meta.updateTag({ name: 'description', content: desc }) }}
After injecting the SEOService in your component (app.component.ts preferably), set meta tags and title in OnInit method
ngOnInit() { this.router.events.pipe( filter((event) => event instanceof NavigationEnd), map(() => this.activatedRoute), map((route) => { while (route.firstChild) route = route.firstChild; return route; }), filter((route) => route.outlet === 'primary'), mergeMap((route) => route.data) ) .subscribe((event) => { this._seoService.updateTitle(event['title']); this._seoService.updateOgUrl(event['ogUrl']); //Updating Description tag dynamically with title this._seoService.updateDescription(event['title'] + event['description']) }); }
Then configure your routes like
{ path: 'about', component: AboutComponent, data: { title: 'About', description:'Description Meta Tag Content', ogUrl: 'your og url' } },
IMHO this is a clear way of dealing with meta tags. You can update facebook and twitter specific tags easier.
Angular 6+ and RxJS 6+ solution for dynamically set title on route change
If/when you upgrade to Angular 6 this is the solution there.
This service will:
- Update meta title on route change.
- Option to override title for any reasons you want that.
Create/change your SEO/meta service to the following.
import { Injectable } from '@angular/core';import { Title, Meta } from '@angular/platform-browser';import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';import { filter, map, mergeMap } from 'rxjs/operators';@Injectable({ providedIn: 'root'})export class MetaService { constructor( private titleService: Title, private meta: Meta, private router: Router, private activatedRoute: ActivatedRoute ) { } updateMetaInfo(content, author, category) { this.meta.updateTag({ name: 'description', content: content }); this.meta.updateTag({ name: 'author', content: author }); this.meta.updateTag({ name: 'keywords', content: category }); } updateTitle(title?: string) { if (!title) { this.router.events .pipe( filter((event) => event instanceof NavigationEnd), map(() => this.activatedRoute), map((route) => { while (route.firstChild) { route = route.firstChild; } return route; }), filter((route) => route.outlet === 'primary'), mergeMap((route) => route.data)).subscribe((event) => { this.titleService.setTitle(event['title'] + ' | Site name'); }); } else { this.titleService.setTitle(title + ' | Site name'); } }}
Import your service and call it in the contructor.
app.component.ts
constructor(private meta: MetaService) { this.meta.updateTitle();}
And this still requires to format routes like this.
Route file.ts
{ path: 'about', component: AboutComponent, data: { title: 'About', description:'Description Meta Tag Content' } },
Hope this will help for you and other people looking to update the title/meta dynamically in Angular 6.
Title
and Meta
are providers that were introduced in Angular 4 and supposed to do this on both server and client side.
To create or update title
tag and description
meta tag, it is:
import { Meta, Title } from '@angular/platform-browser';...constructor(public meta: Meta, public title: Title, ...) { ... }...this.meta.updateTag({ name: 'description', content: description }); this.title.setTitle(title);