Search Results in google are displayed via TitleTag and the <meta name="description"..."/>
Tag. The <title>
-Tag is editiable via Angular2 how to change page title in angular2 router
What's left is the description.
Is it possibile to write a directive in angular2, that manipulates the meta-tags in the <head>
part of my page.
So depending on the selected route, the meta description changes like:
<meta name="description" content="**my description for this route**"/>
Open the HTML file and locate the <head> section near the top of the file. Depending on how you created the page, there may already be a title and some other meta content. The title is between HTML <title></title> tags. The description and keywords are entered in <meta> tags.
Since Angular4, you can use Angular Meta service.
import { Meta } from '@angular/platform-browser'; // [...] constructor(private meta: Meta) {} // [...] this.meta.addTag({ name: 'robots', content: 'noindex' });
It is possible. I implemented it in my app and below I provide the description how it is made.
The basic idea is to use Meta
from @angular/platform-browser
To dynamically change particular meta tag you have to:
removeTag(attrSelector: string) : void
method.addTag(tag: MetaDefinition, forceCreation?: boolean) : HTMLMetaElement
method.And you have to do it when the router fires route change event.
Notice: In fact it is also necessary to have default <title>...</title>
and <meta name="description"..." content="..."/>
in head of index.html so before it is set dynamically there is already some static content.
My app-routing.module.ts
content:
import 'rxjs/add/operator/filter'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/mergeMap'; import { NgModule } from '@angular/core'; import { RouterModule, Routes, Router, NavigationEnd, ActivatedRoute } from '@angular/router'; import { StringComparisonComponent } from '../module-string-comparison/string-comparison.component'; import { ClockCalculatorComponent } from '../module-clock-calculator/clock-calculator.component'; import { Title, Meta } from '@angular/platform-browser'; const routes: Routes = [ { path: '', redirectTo: '/string-comparison', pathMatch: 'full', data: { title: 'String comparison title', metaDescription: 'String comparison meta description content' } }, { path: 'string-comparison', component: StringComparisonComponent, data: { title: 'String comparison title', metaDescription: 'String comparison meta description content' } }, { path: 'clock-time-calculator', component: ClockCalculatorComponent, data: { title: 'Clock time calculator title', metaDescription: 'Clock time calculator meta description content' } } ]; @NgModule({ imports: [ RouterModule.forRoot(routes) ], exports: [ RouterModule ] }) export class AppRoutingModule { constructor( private router: Router, private activatedRoute: ActivatedRoute, private titleService: Title, private metaService: Meta ){ //Boilerplate code to filter out only important router events and to pull out data object field from each route this.router.events .filter(event => event instanceof NavigationEnd) .map(() => this.activatedRoute) .map(route => { while (route.firstChild) route = route.firstChild; return route; }) .filter(route => route.outlet === 'primary') //Data fields are merged so we can use them directly to take title and metaDescription for each route from them .mergeMap(route => route.data) //Real action starts there .subscribe((event) => { //Changing title this.titleService.setTitle(event['title']); //Changing meta with name="description" var tag = { name: 'description', content: event['metaDescription'] }; let attributeSelector : string = 'name="description"'; this.metaService.removeTag(attributeSelector); this.metaService.addTag(tag, false); }); } }
data
object field for each route. It contains title
and metaDescription
strings which will be used as title and meta tag content.if statements
and loops
could be used insead of stream, filter and map.title
and metaDescription
strings.<title>...</title>
and <meta name="description"..." content="..."/>
tags.Effects:
First component
Second component
In fact I currently use a little bit more sophisticated version of this solution which uses also ngx-translate to show different title and meta description for different languages.
Full code is available in angular2-bootstrap-translate-website-starter project.
The app-routing.module.ts
file with ngx-translate solution is exactly there: app-routing.module.ts.
There is also the production app which uses the same solution: http://www.online-utils.com.
For sure it is not the only way and there might be better ways to do it. But I tested this solution and it works.
In fact the solution is very similar to this from corresponding post about changing title: How to change page title in angular2 router.
Angular Meta docs: https://angular.io/docs/ts/latest/api/platform-browser/index/Meta-class.html. In fact they aren't very informative and I had to experiment and look into real .js code to make this dynamic meta change working.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With