Last active
September 22, 2020 17:22
-
-
Save djabif/13f87d2eac7d6d4eb33f77e96f170d4d to your computer and use it in GitHub Desktop.
Angular directive to set dynamic Meta Tags for SEO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Directive, OnDestroy, OnInit, Inject } from '@angular/core'; | |
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; | |
import { Meta, Title } from '@angular/platform-browser'; | |
import { filter, map, mergeMap } from 'rxjs/operators'; | |
import { DOCUMENT, PlatformLocation } from '@angular/common'; | |
@Directive({ | |
selector: '[appSeo]' | |
}) | |
export class SEODirective implements OnInit, OnDestroy { | |
_routerSubscription: any; | |
constructor( | |
private activatedRoute: ActivatedRoute, | |
private router: Router, | |
private meta: Meta, | |
private title: Title, | |
@Inject(DOCUMENT) private document: Document, | |
private platformLocation: PlatformLocation | |
) {} | |
ngOnInit(): void { | |
this._routerSubscription = 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 => { | |
// tslint:disable-next-line:no-string-literal | |
const routeData = event['seo']; | |
if (routeData && routeData.seo) { | |
const title = routeData.seo.title; | |
const description = routeData.seo.description; | |
const keywords = routeData.seo.keywords; | |
const imageUrl = routeData.seo.image_url || 'https://s3-us-west-2.amazonaws.com/ionicthemes/imgs/logofacebook.png'; | |
this.title.setTitle(title); | |
this.meta.updateTag({ name: 'description', content: description }, 'name="description"'); | |
this.meta.updateTag({ name: 'keywords', content: keywords }, 'name="keywords"'); | |
this.meta.updateTag({ name: 'twitter:title', content: title }, 'name="twitter:title"'); | |
this.meta.updateTag({ name: 'twitter:description', content: description }, 'name="twitter:description"'); | |
this.meta.updateTag({ name: 'twitter:image', content: imageUrl }, 'name="twitter:image"'); | |
this.meta.updateTag({ name: 'DC.title', content: title }, 'name="DC.title"'); | |
this.meta.updateTag({ name: 'DC.description', content: description }, 'name="DC.description"'); | |
this.meta.updateTag({ property: 'og:title', content: title }, 'property="og:title"'); | |
this.meta.updateTag({ property: 'og:description', content: description }, 'property="og:description"'); | |
this.meta.updateTag({ property: 'og:image', content: imageUrl }, 'property="og:image"'); | |
} else { | |
// Maybe set default SEO values here | |
} | |
// Set Canonical URL | |
// If you want to set cannonical URL uncomment the following line and add your URL in getCurrentUrl(); | |
// this.updateCanonicalUrl(this.getCurrentUrl(this.platformLocation)); | |
}); | |
} | |
updateCanonicalUrl(url: string) { | |
const head = this.document.getElementsByTagName('head')[0]; | |
let element: HTMLLinkElement = this.document.querySelector(`link[rel='canonical']`) || null; | |
if (element == null) { | |
element= this.document.createElement('link') as HTMLLinkElement; | |
head.appendChild(element); | |
} | |
element.setAttribute('rel','canonical'); | |
element.setAttribute('href', url); | |
} | |
getCurrentUrl(platformLocation: any){ | |
return platformLocation.location.origin + platformLocation.location.pathname; | |
} | |
ngOnDestroy(): void { | |
this._routerSubscription.unsubscribe(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This directive is super helpful to be able to add meta tags dynamically to every route depending on the resolved route data. For example I use it to set the tags for our blog posts and products dynamically.