UNPKG

@davidlj95/ngx-meta

Version:

Set your Angular site's metadata: standard meta tags, Open Graph, Twitter Cards, JSON-LD structured data and more. Supports SSR (and Angular Universal). Use a service. Use routes' data. Set it up in a flash! 🚀

113 lines 12.9 kB
import { Injectable } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/platform-browser"; /** * Manages `<meta>` elements inside `<head>` * * @public */ export class NgxMetaElementsService { constructor(meta) { this.meta = meta; } /** * Creates, updates or removes some kind of `<meta>` elements inside `<head>` in a declarative fashion. * * Kind of `<meta>` elements to manage are identified by an HTML attribute providing its metadata name. * For instance, to manage description metadata elements (`<meta name="description">`) on the page, the * `name` attribute with `description` value identifies them. * * Then, contents for those can be specified. In the shape of a key/value JSON object declaring each element's * additional attributes. Mainly `content` named attributes. See {@link NgxMetaElementAttributes}. * If no contents are provided, all `<meta>` elements of that kind will be removed. * An array of contents may be given to create multiple `<meta>` elements with same kind. * * @example * <b>Setting `<meta name="description" content="Cool page"/>`</b> * * ```typescript * ngxMetaElementsService.set( * withNameAttribute('description'), // same as `['name','description']` * withContent('Cool page'), // same as `{content:'Cool page'}` * ) * ``` * * Utility functions {@link withNameAttribute} and {@link withContentAttribute} help creating the * name attribute identifying the kind of meta elements and the contents to provide for it. * * {@link withContentAttribute} helps to create the attributes key / value object. * * <b>Removing any `<meta name="description"/>` existing elements</b> * * ```typescript * ngxMetaElementsService.set( * withNameAttribute('description'), // same as `['name','description']` * undefined, // same as `withContent(undefined)` * ) * ``` * * <b>Setting many `<meta name="theme-color"/>` elements</b> * * ```typescript * ngxMetaElementsService.set( * withNameAttribute('theme-color'), // same as `['name','theme-color']` * [ * withContent('darkblue', { media: "(prefers-color-scheme: dark)" }), * withContent('lightblue') // same as `{content:'lightblue'}` * ] * ) * ``` * * <b>Removing any `<meta name="theme-color"/>` existing elements</b> * * ```typescript * ngxMetaElementsService.set( * withNameAttribute('theme-color'), // same as `['name','theme-color']` * [], // `undefined` is valid too * ) * ``` * * Attribute name helpers: * * - {@link withNameAttribute} * * - {@link withPropertyAttribute} * * Content helpers: * * - {@link withContentAttribute} * * @param nameAttribute - Attribute use to identify which kind of `<meta>` elements to manage. * As an array with the attribute name in first position and attribute value in second one. * Utility functions exist to generate arrays for common name attributes. * See {@link withNameAttribute} and {@link withPropertyAttribute} helpers to create those * arrays without repeating attribute names around. * * @param content - Content(s) attributes to set for this `<meta>` elements kind. * Or the lack of them to remove all `<meta>` elements of this kind. * See {@link withContentAttribute} helper for creating content objects. */ set(nameAttribute, content) { const [nameAttributeName, nameAttributeValue] = nameAttribute; const attrSelector = `${nameAttributeName}="${nameAttributeValue}"`; this.meta.getTags(attrSelector).forEach((tag) => tag.remove()); /* istanbul ignore next https://github.com/istanbuljs/istanbuljs/issues/719 */ if (!content) { return; } const contents = Array.isArray(content) ? content : [content]; this.meta.addTags(contents.map((content) => ({ [nameAttributeName]: nameAttributeValue, ...content, }))); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxMetaElementsService, deps: [{ token: i1.Meta }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxMetaElementsService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxMetaElementsService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.Meta }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LW1ldGEtZWxlbWVudHMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jb3JlL3NyYy9tZXRhLWVsZW1lbnRzL3YyL25neC1tZXRhLWVsZW1lbnRzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTs7O0FBRzFDOzs7O0dBSUc7QUFFSCxNQUFNLE9BQU8sc0JBQXNCO0lBQ2pDLFlBQW9CLElBQVU7UUFBVixTQUFJLEdBQUosSUFBSSxDQUFNO0lBQUcsQ0FBQztJQUVsQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQTRFRztJQUNILEdBQUcsQ0FDRCxhQUEwQyxFQUMxQyxPQUdhO1FBRWIsTUFBTSxDQUFDLGlCQUFpQixFQUFFLGtCQUFrQixDQUFDLEdBQUcsYUFBYSxDQUFBO1FBQzdELE1BQU0sWUFBWSxHQUFHLEdBQUcsaUJBQWlCLEtBQUssa0JBQWtCLEdBQUcsQ0FBQTtRQUNuRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFBO1FBQzlELDhFQUE4RTtRQUM5RSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixPQUFNO1FBQ1IsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFJLEtBQUssQ0FBQyxPQUEyQixDQUFDLE9BQU8sQ0FBQztZQUMxRCxDQUFDLENBQUMsT0FBTztZQUNULENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ2IsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQ2YsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN6QixDQUFDLGlCQUFpQixDQUFDLEVBQUUsa0JBQWtCO1lBQ3ZDLEdBQUcsT0FBTztTQUNYLENBQUMsQ0FBQyxDQUNKLENBQUE7SUFDSCxDQUFDOytHQXZHVSxzQkFBc0I7bUhBQXRCLHNCQUFzQixjQURULE1BQU07OzRGQUNuQixzQkFBc0I7a0JBRGxDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmd4TWV0YUVsZW1lbnRBdHRyaWJ1dGVzIH0gZnJvbSAnLi9uZ3gtbWV0YS1lbGVtZW50LWF0dHJpYnV0ZXMnXG5pbXBvcnQgeyBNZXRhIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3NlcidcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xuaW1wb3J0IHsgTmd4TWV0YUVsZW1lbnROYW1lQXR0cmlidXRlIH0gZnJvbSAnLi9uZ3gtbWV0YS1lbGVtZW50LW5hbWUtYXR0cmlidXRlJ1xuXG4vKipcbiAqIE1hbmFnZXMgYDxtZXRhPmAgZWxlbWVudHMgaW5zaWRlIGA8aGVhZD5gXG4gKlxuICogQHB1YmxpY1xuICovXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIE5neE1ldGFFbGVtZW50c1NlcnZpY2Uge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1ldGE6IE1ldGEpIHt9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMsIHVwZGF0ZXMgb3IgcmVtb3ZlcyBzb21lIGtpbmQgb2YgYDxtZXRhPmAgZWxlbWVudHMgaW5zaWRlIGA8aGVhZD5gIGluIGEgZGVjbGFyYXRpdmUgZmFzaGlvbi5cbiAgICpcbiAgICogS2luZCBvZiBgPG1ldGE+YCBlbGVtZW50cyB0byBtYW5hZ2UgYXJlIGlkZW50aWZpZWQgYnkgYW4gSFRNTCBhdHRyaWJ1dGUgcHJvdmlkaW5nIGl0cyBtZXRhZGF0YSBuYW1lLlxuICAgKiBGb3IgaW5zdGFuY2UsIHRvIG1hbmFnZSBkZXNjcmlwdGlvbiBtZXRhZGF0YSBlbGVtZW50cyAoYDxtZXRhIG5hbWU9XCJkZXNjcmlwdGlvblwiPmApIG9uIHRoZSBwYWdlLCB0aGVcbiAgICogYG5hbWVgIGF0dHJpYnV0ZSB3aXRoIGBkZXNjcmlwdGlvbmAgdmFsdWUgaWRlbnRpZmllcyB0aGVtLlxuICAgKlxuICAgKiBUaGVuLCBjb250ZW50cyBmb3IgdGhvc2UgY2FuIGJlIHNwZWNpZmllZC4gSW4gdGhlIHNoYXBlIG9mIGEga2V5L3ZhbHVlIEpTT04gb2JqZWN0IGRlY2xhcmluZyBlYWNoIGVsZW1lbnQnc1xuICAgKiBhZGRpdGlvbmFsIGF0dHJpYnV0ZXMuIE1haW5seSBgY29udGVudGAgbmFtZWQgYXR0cmlidXRlcy4gU2VlIHtAbGluayBOZ3hNZXRhRWxlbWVudEF0dHJpYnV0ZXN9LlxuICAgKiBJZiBubyBjb250ZW50cyBhcmUgcHJvdmlkZWQsIGFsbCBgPG1ldGE+YCBlbGVtZW50cyBvZiB0aGF0IGtpbmQgd2lsbCBiZSByZW1vdmVkLlxuICAgKiBBbiBhcnJheSBvZiBjb250ZW50cyBtYXkgYmUgZ2l2ZW4gdG8gY3JlYXRlIG11bHRpcGxlIGA8bWV0YT5gIGVsZW1lbnRzIHdpdGggc2FtZSBraW5kLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiA8Yj5TZXR0aW5nIGA8bWV0YSBuYW1lPVwiZGVzY3JpcHRpb25cIiBjb250ZW50PVwiQ29vbCBwYWdlXCIvPmA8L2I+XG4gICAqXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogbmd4TWV0YUVsZW1lbnRzU2VydmljZS5zZXQoXG4gICAqICAgd2l0aE5hbWVBdHRyaWJ1dGUoJ2Rlc2NyaXB0aW9uJyksIC8vIHNhbWUgYXMgYFsnbmFtZScsJ2Rlc2NyaXB0aW9uJ11gXG4gICAqICAgd2l0aENvbnRlbnQoJ0Nvb2wgcGFnZScpLCAvLyBzYW1lIGFzIGB7Y29udGVudDonQ29vbCBwYWdlJ31gXG4gICAqIClcbiAgICogYGBgXG4gICAqXG4gICAqIFV0aWxpdHkgZnVuY3Rpb25zIHtAbGluayB3aXRoTmFtZUF0dHJpYnV0ZX0gYW5kIHtAbGluayB3aXRoQ29udGVudEF0dHJpYnV0ZX0gaGVscCBjcmVhdGluZyB0aGVcbiAgICogbmFtZSBhdHRyaWJ1dGUgaWRlbnRpZnlpbmcgdGhlIGtpbmQgb2YgbWV0YSBlbGVtZW50cyBhbmQgdGhlIGNvbnRlbnRzIHRvIHByb3ZpZGUgZm9yIGl0LlxuICAgKlxuICAgKiB7QGxpbmsgd2l0aENvbnRlbnRBdHRyaWJ1dGV9IGhlbHBzIHRvIGNyZWF0ZSB0aGUgYXR0cmlidXRlcyBrZXkgLyB2YWx1ZSBvYmplY3QuXG4gICAqXG4gICAqIDxiPlJlbW92aW5nIGFueSBgPG1ldGEgbmFtZT1cImRlc2NyaXB0aW9uXCIvPmAgZXhpc3RpbmcgZWxlbWVudHM8L2I+XG4gICAqXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogbmd4TWV0YUVsZW1lbnRzU2VydmljZS5zZXQoXG4gICAqICAgd2l0aE5hbWVBdHRyaWJ1dGUoJ2Rlc2NyaXB0aW9uJyksIC8vIHNhbWUgYXMgYFsnbmFtZScsJ2Rlc2NyaXB0aW9uJ11gXG4gICAqICAgdW5kZWZpbmVkLCAvLyBzYW1lIGFzIGB3aXRoQ29udGVudCh1bmRlZmluZWQpYFxuICAgKiApXG4gICAqIGBgYFxuICAgKlxuICAgKiA8Yj5TZXR0aW5nIG1hbnkgYDxtZXRhIG5hbWU9XCJ0aGVtZS1jb2xvclwiLz5gIGVsZW1lbnRzPC9iPlxuICAgKlxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIG5neE1ldGFFbGVtZW50c1NlcnZpY2Uuc2V0KFxuICAgKiAgIHdpdGhOYW1lQXR0cmlidXRlKCd0aGVtZS1jb2xvcicpLCAvLyBzYW1lIGFzIGBbJ25hbWUnLCd0aGVtZS1jb2xvciddYFxuICAgKiAgIFtcbiAgICogICAgIHdpdGhDb250ZW50KCdkYXJrYmx1ZScsIHsgbWVkaWE6IFwiKHByZWZlcnMtY29sb3Itc2NoZW1lOiBkYXJrKVwiIH0pLFxuICAgKiAgICAgd2l0aENvbnRlbnQoJ2xpZ2h0Ymx1ZScpIC8vIHNhbWUgYXMgYHtjb250ZW50OidsaWdodGJsdWUnfWBcbiAgICogICBdXG4gICAqIClcbiAgICogYGBgXG4gICAqXG4gICAqIDxiPlJlbW92aW5nIGFueSBgPG1ldGEgbmFtZT1cInRoZW1lLWNvbG9yXCIvPmAgZXhpc3RpbmcgZWxlbWVudHM8L2I+XG4gICAqXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogbmd4TWV0YUVsZW1lbnRzU2VydmljZS5zZXQoXG4gICAqICAgd2l0aE5hbWVBdHRyaWJ1dGUoJ3RoZW1lLWNvbG9yJyksIC8vIHNhbWUgYXMgYFsnbmFtZScsJ3RoZW1lLWNvbG9yJ11gXG4gICAqICAgW10sIC8vIGB1bmRlZmluZWRgIGlzIHZhbGlkIHRvb1xuICAgKiApXG4gICAqIGBgYFxuICAgKlxuICAgKiBBdHRyaWJ1dGUgbmFtZSBoZWxwZXJzOlxuICAgKlxuICAgKiAgLSB7QGxpbmsgd2l0aE5hbWVBdHRyaWJ1dGV9XG4gICAqXG4gICAqICAtIHtAbGluayB3aXRoUHJvcGVydHlBdHRyaWJ1dGV9XG4gICAqXG4gICAqIENvbnRlbnQgaGVscGVyczpcbiAgICpcbiAgICogIC0ge0BsaW5rIHdpdGhDb250ZW50QXR0cmlidXRlfVxuICAgKlxuICAgKiBAcGFyYW0gbmFtZUF0dHJpYnV0ZSAtIEF0dHJpYnV0ZSB1c2UgdG8gaWRlbnRpZnkgd2hpY2gga2luZCBvZiBgPG1ldGE+YCBlbGVtZW50cyB0byBtYW5hZ2UuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgQXMgYW4gYXJyYXkgd2l0aCB0aGUgYXR0cmlidXRlIG5hbWUgaW4gZmlyc3QgcG9zaXRpb24gYW5kIGF0dHJpYnV0ZSB2YWx1ZSBpbiBzZWNvbmQgb25lLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgIFV0aWxpdHkgZnVuY3Rpb25zIGV4aXN0IHRvIGdlbmVyYXRlIGFycmF5cyBmb3IgY29tbW9uIG5hbWUgYXR0cmlidXRlcy5cbiAgICogICAgICAgICAgICAgICAgICAgICAgICBTZWUge0BsaW5rIHdpdGhOYW1lQXR0cmlidXRlfSBhbmQge0BsaW5rIHdpdGhQcm9wZXJ0eUF0dHJpYnV0ZX0gaGVscGVycyB0byBjcmVhdGUgdGhvc2VcbiAgICogICAgICAgICAgICAgICAgICAgICAgICBhcnJheXMgd2l0aG91dCByZXBlYXRpbmcgYXR0cmlidXRlIG5hbWVzIGFyb3VuZC5cbiAgICpcbiAgICogQHBhcmFtIGNvbnRlbnQgLSBDb250ZW50KHMpIGF0dHJpYnV0ZXMgdG8gc2V0IGZvciB0aGlzIGA8bWV0YT5gIGVsZW1lbnRzIGtpbmQuXG4gICAqICAgICAgICAgICAgICAgICAgT3IgdGhlIGxhY2sgb2YgdGhlbSB0byByZW1vdmUgYWxsIGA8bWV0YT5gIGVsZW1lbnRzIG9mIHRoaXMga2luZC5cbiAgICogICAgICAgICAgICAgICAgICBTZWUge0BsaW5rIHdpdGhDb250ZW50QXR0cmlidXRlfSBoZWxwZXIgZm9yIGNyZWF0aW5nIGNvbnRlbnQgb2JqZWN0cy5cbiAgICovXG4gIHNldChcbiAgICBuYW1lQXR0cmlidXRlOiBOZ3hNZXRhRWxlbWVudE5hbWVBdHRyaWJ1dGUsXG4gICAgY29udGVudDpcbiAgICAgIHwgcmVhZG9ubHkgTmd4TWV0YUVsZW1lbnRBdHRyaWJ1dGVzW11cbiAgICAgIHwgTmd4TWV0YUVsZW1lbnRBdHRyaWJ1dGVzXG4gICAgICB8IHVuZGVmaW5lZCxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgW25hbWVBdHRyaWJ1dGVOYW1lLCBuYW1lQXR0cmlidXRlVmFsdWVdID0gbmFtZUF0dHJpYnV0ZVxuICAgIGNvbnN0IGF0dHJTZWxlY3RvciA9IGAke25hbWVBdHRyaWJ1dGVOYW1lfT1cIiR7bmFtZUF0dHJpYnV0ZVZhbHVlfVwiYFxuICAgIHRoaXMubWV0YS5nZXRUYWdzKGF0dHJTZWxlY3RvcikuZm9yRWFjaCgodGFnKSA9PiB0YWcucmVtb3ZlKCkpXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgaHR0cHM6Ly9naXRodWIuY29tL2lzdGFuYnVsanMvaXN0YW5idWxqcy9pc3N1ZXMvNzE5ICovXG4gICAgaWYgKCFjb250ZW50KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY29uc3QgY29udGVudHMgPSAoQXJyYXkuaXNBcnJheSBhcyBpc0NvbnRlbnRzQXJyYXkpKGNvbnRlbnQpXG4gICAgICA/IGNvbnRlbnRcbiAgICAgIDogW2NvbnRlbnRdXG4gICAgdGhpcy5tZXRhLmFkZFRhZ3MoXG4gICAgICBjb250ZW50cy5tYXAoKGNvbnRlbnQpID0+ICh7XG4gICAgICAgIFtuYW1lQXR0cmlidXRlTmFtZV06IG5hbWVBdHRyaWJ1dGVWYWx1ZSxcbiAgICAgICAgLi4uY29udGVudCxcbiAgICAgIH0pKSxcbiAgICApXG4gIH1cbn1cblxudHlwZSBpc0NvbnRlbnRzQXJyYXkgPSAoXG4gIGNvbnRlbnRPckNvbnRlbnRzOlxuICAgIHwgcmVhZG9ubHkgTmd4TWV0YUVsZW1lbnRBdHRyaWJ1dGVzW11cbiAgICB8IE5neE1ldGFFbGVtZW50QXR0cmlidXRlcyxcbikgPT4gY29udGVudE9yQ29udGVudHMgaXMgcmVhZG9ubHkgTmd4TWV0YUVsZW1lbnRBdHRyaWJ1dGVzW11cbiJdfQ==