@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
JavaScript
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==