description change angular typescript angular-ui-router

change - Añadir dinámicamente meta descripción basada en ruta en Angular



meta tags angular 4 (5)

Estoy usando Angular 5 para construir un pequeño sitio web tipo folleto. Hasta ahora, tengo mis rutas configuradas y el título de la página cambia dinámicamente según la ruta activada. Conseguí este trabajo usando las instrucciones en este blog: https://toddmotto.com/dynamic-page-titles-angular-2-router-events

Actualmente estoy almacenando mis rutas y títulos en app.module.ts como tal:

imports: [ BrowserModule, RouterModule.forRoot([ { path: '''', component: HomeComponent, data: { title: ''Home'' } }, { path: ''about'', component: AboutComponent, data: { title: ''About'' } }, { path: ''products-and-services'', component: ProductsServicesComponent, data: { title: ''Products & Services'' } }, { path: ''world-class-laundry'', component: LaundryComponent, data: { title: ''World Class Laundry'' } }, { path: ''contact'', component: ContactComponent, data: { title: ''Contact'' } }, { path: ''**'', component: NotFoundComponent, data: { title: ''Page Not Found'' } } ]) ],

También me gustaría almacenar mis meta descripciones allí, si las agrego bajo data: sería bastante fácil.

Estoy ingresando los datos de ese título con el siguiente código, que se indica en el enlace del blog anterior:

ngOnInit() { 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'') .mergeMap((route) => route.data) .subscribe((event) => { this.titleService.setTitle(event[''title'']); }); }

Entonces, mi pregunta es, ¿hay una manera de establecer dinámicamente la meta descripción usando el mismo método? Si hay una manera de combinar el título de la página y la función de descripción meta, sería ideal.

Tengo un entrenamiento angular muy limitado, por lo que esta podría ser una pregunta nooby. Soy más de un tipo de diseñador / css / html.


Primero crea un SEOService o algo como a continuación:

import {Injectable} from ''@angular/core''; import { Meta, Title } from ''@angular/platform-browser''; @Injectable() export class SEOService { constructor(private title: Title, private meta: Meta) { } updateTitle(title: string) { this.title.setTitle(title); } updateDescription(desc: string) { this.meta.updateTag({ name: ''description'', content: desc }) }

Después de inyectar el servicio SEOS en su componente, configure las metaetiquetas y el título en el método OnInit

ngOnInit() { 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'') .mergeMap((route) => route.data) .subscribe((event) => { this._seoService.updateTitle(event[''title'']); //Updating Description tag dynamically with title this._seoService.updateDescription(event[''title''] + event[''description'']) }); }

Edición: Para RxJs 6+ que usa un operador de tubería

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'']); //Updating Description tag dynamically with title this._seoService.updateDescription(event[''title''] + event[''description'']) }); }

Luego configura tus rutas como

{ path: ''about'', component: AboutComponent, data: { title: ''About'', description:''Description Meta Tag Content'' } },

En mi humilde opinión, esta es una forma clara de tratar con las etiquetas meta. Puedes actualizar las etiquetas específicas de facebook y twitter más fácilmente.


Puede hacer lo siguiente desde Angular (en realidad, la solución solo necesita jQuery, no algo particular de Angular)

En la configuración del router:

{ path: ''about'', component: AboutComponent, data: { title: ''About'', description: ''Here some description'' } },

En su componente:

... .subscribe((event) => { this.titleService.setTitle(event[''title'']); $(''meta[name=description]'').attr(''content'', event[''description'']); });

Si no desea utilizar jQuery, existen funciones simples de JavaScript para encontrar los elementos meta y cambiar sus atributos ( getElementsByTagName y getAttribute ). El código completo para la alternativa de JavaScript se puede encontrar en esta otra pregunta SO aquí .

Nota: También consideraría almacenar el título y la descripción como campos privados en los propios componentes, en lugar de en la configuración del enrutador. Esto evita la necesidad de suscribirse a cualquier cosa, y deja solo las cosas relacionadas con el enrutador en la configuración del enrutador.


Title y angular.io/api/platform-browser/Meta son proveedores que se introdujeron en Angular 4 y se supone que deben hacer esto tanto en el servidor como en el lado del cliente.

Para crear o actualizar la etiqueta del title y la etiqueta meta de la description , es:

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);


Aquí están las partes relevantes de mi proyecto. (Angular 2/4)

app-routing.module.ts:

Rutas:

... const appRoutes: Routes = [ { path: ''path1'', loadChildren: ''./path1#path1Module'', data: { title: ''...'', description: ''...'', keywords: ''...'' } }, { path: ''path2'', loadChildren: ''./path2#path2Module'', data: { title: ''...'', description: ''...'', keywords: ''...'' } } ...

app.component.ts (o su componente bootstrap):

importaciones:

// imports import { Component, OnInit} from ''@angular/core''; import { Router, ActivatedRoute, NavigationEnd } from ''@angular/router''; import ''rxjs/add/operator/filter''; import ''rxjs/add/operator/map''; import ''rxjs/add/operator/mergeMap''; import { Title,Meta } from ''@angular/platform-browser'';

constructor:

// constructor: constructor(private router: Router, private route: ActivatedRoute, private titleService: Title, private meta: Meta) {}

Método ngOnInit ():

ngOnInit() { this.router.events .filter((event) => event instanceof NavigationEnd) .map(() => this.route) .map((route) => { while (route.firstChild) route = route.firstChild; return route; }) .filter((route) => route.outlet === ''primary'') .mergeMap((route) => route.data) .subscribe((event) => { this.updateDescription(event[''description''], event[''keywords''], event[''title'']); }); }

método que actualiza las etiquetas de título y meta -> llamadas desde ngOnInit ():

updateDescription(desc: string, keywords: string, title: string) { this.titleService.setTitle(title); this.meta.updateTag({ name: ''description'', content: desc }) this.meta.updateTag({ name: ''keywords'', content: keywords }) this.meta.updateTag({ name: ''og:title'', content: title }) this.meta.updateTag({ name: ''og:description'', content: desc }) }

Espero eso ayude.


Solución Angular 6+ y RxJS 6+ para establecer títulos de forma dinámica en el cambio de ruta

Si / cuando actualizas a Angular 6 esta es la solución.

Este servicio:

  • Actualizar el título del meta en el cambio de ruta.
  • Opción de anular el título por cualquier motivo que desee.

Crea / cambia tu servicio SEO / meta a lo siguiente.

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''); } } }

Importa tu servicio y llámalo en el contructor.

app.component.ts

constructor(private meta: MetaService) { this.meta.updateTitle(); }

Y esto todavía requiere formatear rutas como esta.

Archivo de ruta.ts

{ path: ''about'', component: AboutComponent, data: { title: ''About'', description:''Description Meta Tag Content'' } },

Espero que esto ayude a usted y otras personas que buscan actualizar el título / meta dinámicamente en Angular 6.