web-dev-qa-db-fra.com

Ajoutez dynamiquement une méta-description basée sur la route dans Angular

J'utilise Angular 5 pour créer un petit site Web de type brochure. Jusqu'à présent, mes itinéraires sont configurés et le titre de la page change de manière dynamique en fonction de l'itinéraire activé. les instructions sur ce blog: https://toddmotto.com/dynamic-page-titles-angular-2-router-events

Je stocke actuellement mes itinéraires et mes titres dans app.module.ts en tant que tels:

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'
        }  
      }
    ])
  ],

J'aimerais aussi y stocker mes méta-descriptions, si je les ajoute sous data: serait assez facile.

J'insère ces données de titre avec le code suivant, indiqué dans le lien du blog ci-dessus:

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

Ma question est donc la suivante: existe-t-il un moyen de définir dynamiquement la méta-description en utilisant la même méthode? S'il existe un moyen de combiner le titre de la page et la fonction de méta-description, ce serait l'idéal.

J'ai une formation très limitée Angular), donc ce n'est peut-être pas une question banale. Je suis plutôt du genre concepteur/css/html.

38
Kellen

Commencez par créer un service SEOS ou quelque chose comme ci-dessous:

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

  updateOgUrl(url: string) {
    this.meta.updateTag({ name: 'og:url', content: url })
  }

  updateDescription(desc: string) {
    this.meta.updateTag({ name: 'description', content: desc })
  }

Après avoir injecté SEOService dans votre composant, définissez les balises méta et le titre dans la méthode 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']);
    this._seoService.updateOgUrl(event['ogUrl']);
    //Updating Description tag dynamically with title
    this._seoService.updateDescription(event['title'] + event['description'])
  }); 
}

Edit: Pour les RxJs 6+ utilisant un opérateur de pipe

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

Puis configurez vos itinéraires comme

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

IMHO c'est un moyen clair de traiter les balises méta. Vous pouvez mettre à jour plus facilement les balises spécifiques à Facebook et Twitter.

38
Okan Aslankan

Title et Meta sont des fournisseurs qui ont été introduits dans Angular 4 et censés le faire le les deux côté serveur et client.

Pour créer ou mettre à jour la balise méta title et la balise méta description, procédez comme suit:

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);
6
Estus Flask

Solution angulaire 6+ et RxJS 6+ pour définir le titre de manière dynamique lors du changement de route

Si/lorsque vous effectuez une mise à niveau vers Angular 6, voilà la solution.

Ce service va:

  • Mettre à jour le méta-titre sur le changement d'itinéraire.
  • Option pour remplacer le titre pour toutes les raisons que vous voulez.

Créez/modifiez votre service de référencement/méta comme suit.

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

Importez votre service et appelez-le dans le constructeur.

app.component.ts

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

Et cela nécessite encore de formater des routes comme celle-ci.

Route file.ts

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

J'espère que cela aidera pour vous et les autres personnes qui cherchent à mettre à jour le titre/méta de manière dynamique dans Angular 6.

4
Walgermo