UNPKG

ngmeta

Version:

A tool for updating meta tags in an Angular application.

253 lines 9.45 kB
import { Injectable, Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import * as i0 from "@angular/core"; import * as i1 from "@angular/platform-browser"; /** * Service that allows setting and updating of meta tags, title tags, and canonical tags. */ export class NgMeta { constructor(_title, _meta, _dom) { this._title = _title; this._meta = _meta; this._dom = _dom; this._scroll = false; } /** * Returns native Angular service for managing HTML `<meta>` tags. * * @return Native Angular service for managing HTML `<meta>` tags. */ get meta() { return this._meta; } /** * Scroll to top of page. * * @return Current instance of the NgMeta service. */ scrollToTop() { if (this._scroll && typeof window !== 'undefined' && !window.location.pathname.includes('#')) { window.scrollTo(0, 0); } return this; } /** * Sets all meta details for page. * * @param param0 All meta details in head. * @return Current instance of the NgMeta service. */ setAll({ title, description, image, canonical = this._dom.URL, twitter, }) { this.setTitle(title); this.setDescription(description); this.setFacebook({ title, description, image, url: canonical }); this.setGoogle({ title, description, image }); this.setTwitter({ title, description, image, site: twitter }); this.setCanonical(canonical); this.scrollToTop(); return this; } /** * Sets canonical URL of web page. * * @param canonical The canonical URL for your page. * @return Current instance of the NgMeta service. */ setCanonical(canonical = this._dom.URL) { let element = this._dom.querySelector("link[rel='canonical']"); if (!element) { element = this._dom.createElement('link'); element.setAttribute('rel', 'canonical'); this._dom.head.appendChild(element); } element.setAttribute('href', canonical); return this; } /** * Sets description of web page. * * @param description Description relating to the content of page. * @return Current instance of the NgMeta service. */ setDescription(description = '') { const name = 'description'; const elements = this._meta.getTags(`name="${name}"`); if (elements.length) { this._meta.updateTag({ name: 'description', content: description }, `name="${name}"`); } else { this._meta.addTag({ name: 'description', content: description }); } return this; } /** * Sets Open Graph tags for optimal display on Facebook. * * @param param0 All Facebook Open Graph meta details in head. * @return Current instance of the NgMeta service. */ setFacebook({ locale, type, title, description, image, url = this._dom.URL, appId, }) { const fields = [ { property: 'og:locale', content: locale }, { property: 'og:type', content: type }, { property: 'og:title', content: title }, { property: 'og:description', content: description }, { property: 'og:image', content: image }, { property: 'og:url', content: url }, { property: 'fb:app_id', content: appId }, ]; fields.forEach(field => { if (field.content) { const elements = this._meta.getTags(`property="${field.property}"`); if (elements.length) { this._meta.updateTag({ property: field.property, content: field.content }, `property="${field.property}"`); } else { this._meta.updateTag({ property: field.property, content: field.content, }); } } }); return this; } /** * Sets microdata tags for optimal display on Google. * * @param param0 All Google microdata meta details in head. * @return Current instance of the NgMeta service. */ setGoogle({ title, description, image }) { const fields = [ { itemprop: 'title', content: title }, { itemprop: 'description', content: description }, { itemprop: 'image', content: image }, ]; fields.forEach(field => { if (field.content) { const elements = this._meta.getTags(`itemprop="${field.itemprop}"`); if (elements.length) { this._meta.updateTag({ itemprop: field.itemprop, content: field.content }, `itemprop="${field.itemprop}"`); } else { this._meta.updateTag({ itemprop: field.itemprop, content: field.content, }); } } }); return this; } /** * Sets if after `setAll` window will scroll to top. * * @param scroll Boolean of wether to scroll to top or not. * @return Current instance of the NgMeta service. */ setScroll(scroll) { this._scroll = scroll; return this; } /** * Sets a HTML element in the head with any attributes defined in object. * @param tagType Tag name of HTML Element. * @param tagData Details for tag to set in head. * @param overwrite Whether this method should overwrite an existing instance of the tag. Set to false by default. * @return Current instance of the NgMeta service. */ setTag(tagType, tagData, overwrite = false) { const element = this._dom.createElement(tagType); if (overwrite) { switch (tagType) { case 'base': this._meta.removeTag('base'); break; case 'link': if (tagData.href) { this._meta.removeTag(`link[href='${tagData.href}']`); } break; case 'meta': if (tagData.name) { this._meta.removeTag(`meta[name='${tagData.name}']`); } break; case 'script': if (tagData.src) { this._meta.removeTag(`script[src='${tagData.src}']`); } break; } } Object.keys(tagData).forEach((attribute) => { const value = tagData[attribute]; if (['innerHTML', 'innerText', 'textContent'].includes(attribute)) { if (typeof value === 'string') { element[attribute] = value; } } else if (typeof value === 'boolean' || value === undefined) { if (value) { element.setAttribute(attribute, ''); } } else { element.setAttribute(attribute, value.toString()); } }); this._dom.head.appendChild(element); return this; } /** * Sets document's title shown in a browser's title bar or a page's tab. * * @param title Document's title. * @return Current instance of the NgMeta service. */ setTitle(title = '') { this._title.setTitle(title); return this; } /** * Sets tags for optimal display as a Twitter card. * * @param param0 All Twitter microdata meta details in head. * @return Current instance of the NgMeta service. */ setTwitter({ title, description, image, alt, site }) { const fields = [ { name: 'twitter:card', content: 'summary_large_image' }, { name: 'twitter:title', content: title }, { name: 'twitter:description', content: description }, { name: 'twitter:image', content: image }, { name: 'twitter:image:alt', content: (image && alt) || (image && title) }, { name: 'twitter:site', content: site }, ]; fields.forEach(field => { if (field.content) { const elements = this._meta.getTags(`name="${field.name}"`); if (elements.length) { this._meta.updateTag({ name: field.name, content: field.content }, `name="${field.name}"`); } else { this._meta.updateTag({ name: field.name, content: field.content }); } } }); return this; } } NgMeta.ɵfac = function NgMeta_Factory(t) { return new (t || NgMeta)(i0.ɵɵinject(i1.Title), i0.ɵɵinject(i1.Meta), i0.ɵɵinject(DOCUMENT)); }; NgMeta.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: NgMeta, factory: NgMeta.ɵfac }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NgMeta, [{ type: Injectable }], function () { return [{ type: i1.Title }, { type: i1.Meta }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }]; }, null); })(); //# sourceMappingURL=ngmeta.service.js.map