Comment ajouter un lien canonique en angle 5 dynamiquement
<link rel="canonical" href="http://foobar.com/gotcah"/>
J'ai la solution, créer le service de lien (ex: link.service.ts) et coller le code ci-dessous
import { Injectable, Optional, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
@Injectable()
export class LinkService {
constructor(
private rendererFactory: RendererFactory2,
@Inject(DOCUMENT) private document
) {
}
/**
* Inject the State into the bottom of the <head>
*/
addTag(tag: LinkDefinition, forceCreation?: boolean) {
try {
const renderer = this.rendererFactory.createRenderer(this.document, {
id: '-1',
encapsulation: ViewEncapsulation.None,
styles: [],
data: {}
});
const link = renderer.createElement('link');
const head = this.document.head;
const selector = this._parseSelector(tag);
if (head === null) {
throw new Error('<head> not found within DOCUMENT.');
}
Object.keys(tag).forEach((prop: string) => {
return renderer.setAttribute(link, prop, tag[prop]);
});
// [TODO]: get them to update the existing one (if it exists) ?
renderer.appendChild(head, link);
} catch (e) {
console.error('Error within linkService : ', e);
}
}
private _parseSelector(tag: LinkDefinition): string {
// Possibly re-work this
const attr: string = tag.rel ? 'rel' : 'hreflang';
return `${attr}="${tag[attr]}"`;
}
}
export declare type LinkDefinition = {
charset?: string;
crossorigin?: string;
href?: string;
hreflang?: string;
media?: string;
rel?: string;
rev?: string;
sizes?: string;
target?: string;
type?: string;
} & {
[prop: string]: string;
};
service d'importation en composant:
import { LinkService } from '../link.service';
constructor(private linkService: LinkService) {
this.linkService.addTag( { rel: 'canonical', href: 'url here'} );
}
veuillez vous référer au lien ci-dessous:
Face au même problème, j'ai cherché et trouvé un guide sur la façon de procéder:
https://www.concretepage.com/angular/angular-title-service-and-canonical-url
Il utilise cependant Angular 6, mais je pense qu’il est rétrocompatible à 5.
Il suggère fondamentalement de créer un service (SEOService) pour faciliter la création du lien canonique, où qu’il soit injecté. Il injecte l'objet Angular DOCUMENT
dans le service et crée l'élément de lien canonique en tant que HTMLLinkElement
.
Elle veille à ce que la solution prérendering/rend des serveurs conviviale - donc si vous cherchez à mieux contrôler votre référencement pour les pages de votre application, je pense que c'est ce que vous voulez.
Voici une réécriture minimale du service de l'article:
seo.service.ts
import { Injectable, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
@Injectable({
providedIn: 'root'
})
export class SeoService {
constructor(@Inject(DOCUMENT) private doc) {}
createLinkForCanonicalURL() {
let link: HTMLLinkElement = this.doc.createElement('link');
link.setAttribute('rel', 'canonical');
this.doc.head.appendChild(link);
link.setAttribute('href', this.doc.URL);
}
}
Et voici une réécriture du composant consommant le service:
data.component.ts
import { Component, OnInit } from '@angular/core';
import { SeoService } from './seo.service';
@Component({
selector: 'app-data',
templateUrl: './data.component.html'
})
export class DataComponent implements OnInit {
constructor(private seoService: SEOService) { }
ngOnInit() {
this.createLinkForCanonicalURL();
}
createLinkForCanonicalURL() {
this.seoService.createLinkForCanonicalURL();
}
}
Vous pourriez simplement demander à la méthode createLinkForCanonicalURL()
de prendre un paramètre facultatif de l'URL que vous souhaiteriez comme référence canonique pour la page, pour un contrôle total.