diff --git a/src/app/core/canonocal-url/canonocal-url.service.spec.ts b/src/app/core/canonocal-url/canonocal-url.service.spec.ts new file mode 100644 index 0000000000..c8d5348657 --- /dev/null +++ b/src/app/core/canonocal-url/canonocal-url.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing' + +import { CanonocalUrlService } from './canonocal-url.service' + +describe('CanonocalUrlService', () => { + let service: CanonocalUrlService + + beforeEach(() => { + TestBed.configureTestingModule({}) + service = TestBed.inject(CanonocalUrlService) + }) + + it('should be created', () => { + expect(service).toBeTruthy() + }) +}) diff --git a/src/app/core/canonocal-url/canonocal-url.service.ts b/src/app/core/canonocal-url/canonocal-url.service.ts new file mode 100644 index 0000000000..ea3cc7102e --- /dev/null +++ b/src/app/core/canonocal-url/canonocal-url.service.ts @@ -0,0 +1,54 @@ +import { DOCUMENT } from '@angular/common' +import { Inject, Injectable } from '@angular/core' +import { NavigationEnd, Router } from '@angular/router' +import { filter, map } from 'rxjs/operators' +import { ORCID_REGEXP } from 'src/app/constants' +import { environment } from 'src/environments/environment' + +@Injectable({ + providedIn: 'root', +}) +export class CanonocalUrlService { + constructor(@Inject(DOCUMENT) private doc: any, private _router: Router) { + this.init() + } + + private init() { + this._router.events + .pipe( + filter((event) => event instanceof NavigationEnd), + map((event: NavigationEnd) => event as NavigationEnd) + ) + .subscribe((event) => { + if ( + event?.url.startsWith('/my-orcid') || + !ORCID_REGEXP.test(event?.url) + ) { + // Remove canonical url if the route is not public page + this.removeCanonicalUrl() + } + }) + } + + setCanonicalUrl(publicOrcid) { + // Just in case there is another canonical link already + this.removeCanonicalUrl() + let canonicalUrl = + 'https:' + + environment.BASE_URL + + (environment.BASE_URL.endsWith('/') ? publicOrcid : '/' + publicOrcid) + let link: HTMLLinkElement = this.doc.createElement('link') + + link.setAttribute('rel', 'canonical') + link.setAttribute('href', canonicalUrl) + this.doc.head.appendChild(link) + } + removeCanonicalUrl() { + this.doc.head.querySelectorAll('link').forEach((link) => { + let attributeRel = link.getAttribute('rel') + if (attributeRel && attributeRel == 'canonical') { + link.parentNode.removeChild(link) + } + }) + } +} diff --git a/src/app/record/pages/my-orcid/my-orcid.component.ts b/src/app/record/pages/my-orcid/my-orcid.component.ts index 18012b96d1..df00ce5585 100644 --- a/src/app/record/pages/my-orcid/my-orcid.component.ts +++ b/src/app/record/pages/my-orcid/my-orcid.component.ts @@ -5,7 +5,7 @@ import { OnDestroy, OnInit, } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' +import { ActivatedRoute, NavigationEnd, Router } from '@angular/router' import { PlatformInfo, PlatformInfoService } from 'src/app/cdk/platform-info' import { ORCID_REGEXP } from 'src/app/constants' import { first, switchMap, take, takeUntil, tap } from 'rxjs/operators' @@ -21,6 +21,10 @@ import { WINDOW } from 'src/app/cdk/window' import { TogglzService } from 'src/app/core/togglz/togglz.service' import { HelpHeroService } from 'src/app/core/help-hero/help-hero.service' import { ScriptService } from '../../../core/crazy-egg/script.service' +import { DOCUMENT } from '@angular/common' +import { environment } from 'src/environments/environment' +import { filter, map } from 'rxjs/operators' +import { CanonocalUrlService } from 'src/app/core/canonocal-url/canonocal-url.service' @Component({ selector: 'app-my-orcid', @@ -80,7 +84,7 @@ export class MyOrcidComponent implements OnInit, OnDestroy { @Inject(WINDOW) private window: Window, private _togglz: TogglzService, private _scriptService: ScriptService, - private _changeDetectorRef: ChangeDetectorRef + private _canonocalUrlService: CanonocalUrlService ) {} private checkIfThisIsAPublicOrcid() { @@ -106,6 +110,11 @@ export class MyOrcidComponent implements OnInit, OnDestroy { ngOnInit(): void { this.checkIfThisIsAPublicOrcid() this.affiliations = 0 + + if (this.publicOrcid) { + this._canonocalUrlService.setCanonicalUrl(this.publicOrcid) + } + // Remove fragment temporally, to adding back when items have loaded this.route.fragment.pipe(take(1)).subscribe((fragment) => { if (fragment) {