Socket
Socket
Sign inDemoInstall

react-metatags-hook

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-metatags-hook - npm Package Compare versions

Comparing version 1.1.2 to 1.2.0

5

CHANGELOG.md

@@ -0,1 +1,6 @@

## [1.2.0] - 2020-04-12
### Changed
* `id` is used to identify unique tags.
* Upgraded all dependencies.
## [1.1.1] - 2019-10-09

@@ -2,0 +7,0 @@ ### Added

16

dist/index.cjs.js

@@ -1,2 +0,16 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var react=require("react"),__assign=function(){return(__assign=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var a in t=arguments[n])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e}).apply(this,arguments)};function __spreadArrays(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),a=0;for(t=0;t<n;t++)for(var u=arguments[t],o=0,i=u.length;o<i;o++,a++)r[a]=u[o];return r}var domChangeTimeout,queryableKeys={meta:["charset","name","property","http-equiv"],link:["rel","sizes"]},createInternalTag=function(e){return function(t){var n=queryableKeys[e].map((function(e){return t.hasOwnProperty(e)?{key:e,value:t[e]}:void 0})).filter(Boolean),r=Object.keys(t).map((function(e){return{key:e,value:t[e]}}));return{tag:e,query:n.length?n:r,attributes:t}}},createInternalMeta=createInternalTag("meta"),createInternalLink=createInternalTag("link"),parseMetaConfig=function(e){var t=e.title,n=e.description,r=e.lang,a=e.charset,u=e.metas,o=void 0===u?[]:u,i=e.links,s=void 0===i?[]:i,c=e.openGraph,g=void 0===c?{}:c,m=e.twitter,l=void 0===m?{}:m;return{title:t,lang:r,tags:__spreadArrays([!!n&&{tag:"meta",query:[{key:"name",value:"description"}],attributes:{name:"description",content:n}},!!a&&{tag:"meta",query:[{key:"charset"}],attributes:{charset:a}}],o.map(createInternalMeta),s.map(createInternalLink),Object.keys(g).map((function(e){return createInternalMeta({property:"og:"+e,content:g[e]})})),Object.keys(l).map((function(e){return createInternalMeta({property:"twitter:"+e,content:l[e]})}))).filter((function(e){return e&&e.query&&Object.keys(e.query).length})).reduce((function(e,t){var n,r=t.query.map((function(e){var t=e.key,n=void 0===t?"":t,r=e.value;return n+"="+(void 0===r?"":r)})).join("~"),a=t.tag+"_"+r;return __assign(__assign({},e),((n={})[a]=t,n))}),{})}},metaStore=new Set,subscribers=new Set,mergeInstanceConfigs=function(e){return Array.from(e).map((function(e){return e.current})).reduce((function(e,t){return __assign(__assign(__assign({},e),t),{tags:__assign(__assign({},e.tags),t.tags)})}),{tags:{}})},emitChanges=function(e){subscribers.forEach((function(t){return t(e)}))},addMetasToStore=function(e){!metaStore.has(e)&&metaStore.add(e),emitChanges(mergeInstanceConfigs(metaStore))},removeMetasFromStore=function(e){metaStore.delete(e),emitChanges(mergeInstanceConfigs(metaStore))},subscribeToStore=function(e){return subscribers.add(e),function(){subscribers.delete(e)}},getState=function(){return mergeInstanceConfigs(metaStore)},getRemovedTags=function(e,t){return Object.keys(t.tags||{}).filter((function(t){return!e.tags[t]})).map((function(e){return t.tags[e]}))},getTagsList=function(e){return Object.keys(e.tags||{}).map((function(t){return e.tags[t]}))},getHeadElement=function(e,t){var n=t.reduce((function(e,t){var n=t.key,r=t.value;return e+"["+n+(r?'="'+r+'"':"")+"]"}),"");return document.head.querySelector(e+n)},createHeadElement=function(e){var t=document.createElement(e);return document.head.appendChild(t),t},setTitle=function(e){document.title=e},setLang=function(e){document.documentElement.lang=e},setHeadElement=function(e){var t=e.tag,n=e.query,r=e.attributes,a=getHeadElement(t,n)||createHeadElement(t);r&&Object.keys(r).forEach((function(e){a.setAttribute(e,r[e]||"")}))},removeHeadElement=function(e){var t=e.tag,n=e.query,r=getHeadElement(t,n);r&&document.head.removeChild(r)},lastMetas={tags:{}},updateDom=function(e,t){"undefined"!=typeof window&&(window.clearTimeout(domChangeTimeout),domChangeTimeout=setTimeout((function(){var t=getRemovedTags(e,lastMetas),n=getTagsList(e);lastMetas=e,e.title&&setTitle(e.title),e.lang&&setLang(e.lang),n.forEach(setHeadElement),t.forEach(removeHeadElement)}),t))},generateMetasMarkup=function(e){return __spreadArrays([e.title?"<title>"+e.title+"</title>":""],getTagsList(e).map((function(e){var t=e.attributes;return"<"+e.tag+" "+Object.keys(t).map((function(e){return""+e+(t[e]?'="'+t[e]+'"':"")})).join(" ")+" />"}))).join("")};subscribeToStore((function(e){return updateDom(e,50)}));var generateStaticHtml=function(){var e=getState();return generateMetasMarkup(e)},useMetaTags=function(e,t){var n=react.useRef(),r=react.useMemo((function(){return parseMetaConfig(e)}),t);react.useEffect((function(){return function(){n.current&&removeMetasFromStore(n)}}),[]),n.current!==r&&(n.current=r,n.current&&addMetasToStore(n))};exports.default=useMetaTags,exports.generateStaticHtml=generateStaticHtml;
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),e=function(){return(e=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var u in e=arguments[n])Object.prototype.hasOwnProperty.call(e,u)&&(t[u]=e[u]);return t}).apply(this,arguments)};
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */function n(){for(var t=0,e=0,n=arguments.length;e<n;e++)t+=arguments[e].length;var r=Array(t),u=0;for(e=0;e<n;e++)for(var a=arguments[e],o=0,i=a.length;o<i;o++,u++)r[u]=a[o];return r}var r,u,a={meta:["charset","name","property","http-equiv"],link:["rel","sizes"]},o=function(t){return function(e){var n=a[t].concat("id").map((function(t){return e.hasOwnProperty(t)?{key:t,value:e[t]}:void 0})).filter(Boolean),r=Object.keys(e).map((function(t){return{key:t,value:e[t]}}));return{tag:t,query:n.length?n:r,attributes:e}}},i=o("meta"),c=o("link"),f=new Set,s=new Set,l=function(t){return Array.from(t).map((function(t){return t.current})).reduce((function(t,n){return e(e(e({},t),n),{tags:e(e({},t.tags),n.tags)})}),{tags:{}})},d=function(t){s.forEach((function(e){return e(t)}))},p=function(t){return Object.keys(t.tags||{}).map((function(e){return t.tags[e]}))},m=function(t,e){var n=e.reduce((function(t,e){var n=e.key,r=e.value;return t+"["+n+(r?'="'+r+'"':"")+"]"}),"");return document.head.querySelector(t+n)},y=function(t){var e,n,r=t.tag,u=t.query,a=t.attributes,o=m(r,u)||(e=r,n=document.createElement(e),document.head.appendChild(n),n);a&&Object.keys(a).forEach((function(t){o.setAttribute(t,a[t]||"")}))},v=function(t){var e=t.tag,n=t.query,r=m(e,n);r&&document.head.removeChild(r)},g={tags:{}},h=function(t,e){"undefined"!=typeof window&&(window.clearTimeout(r),r=setTimeout((function(){var e,n,r=function(t,e){return Object.keys(e.tags||{}).filter((function(e){return!t.tags[e]})).map((function(t){return e.tags[t]}))}(t,g),u=p(t);g=t,t.title&&(e=t.title,document.title=e),t.lang&&(n=t.lang,document.documentElement.lang=n),u.forEach(y),r.forEach(v)}),e))};u=function(t){return h(t,50)},s.add(u);exports.default=function(r,u){var a=t.useRef(),o=t.useMemo((function(){return function(t){var r=t.title,u=t.description,a=t.lang,o=t.charset,f=t.metas,s=void 0===f?[]:f,l=t.links,d=void 0===l?[]:l,p=t.openGraph,m=void 0===p?{}:p,y=t.twitter,v=void 0===y?{}:y;return{title:r,lang:a,tags:n([!!u&&{tag:"meta",query:[{key:"name",value:"description"}],attributes:{name:"description",content:u}},!!o&&{tag:"meta",query:[{key:"charset"}],attributes:{charset:o}}],s.map(i),d.map(c),Object.keys(m).map((function(t){return i({property:"og:"+t,content:m[t]})})),Object.keys(v).map((function(t){return i({property:"twitter:"+t,content:v[t]})}))).filter((function(t){return t&&t.query&&Object.keys(t.query).length})).reduce((function(t,n){var r,u=n.query.map((function(t){var e=t.key,n=void 0===e?"":e,r=t.value;return n+"="+(void 0===r?"":r)})).join("~"),a=n.tag+"_"+u;return e(e({},t),((r={})[a]=n,r))}),{})}}(r)}),u);t.useEffect((function(){return function(){a.current&&function(t){f.delete(t),d(l(f))}(a)}}),[]),a.current!==o&&(a.current=o,a.current&&function(t){!f.has(t)&&f.add(t),d(l(f))}(a))},exports.generateStaticHtml=function(){return function(t){return n([t.title?"<title>"+t.title+"</title>":""],p(t).map((function(t){var e=t.attributes;return"<"+t.tag+" "+Object.keys(e).map((function(t){return""+t+(e[t]?'="'+e[t]+'"':"")})).join(" ")+" />"}))).join("")}(l(f))};
//# sourceMappingURL=index.cjs.js.map

5

dist/state/store.d.ts
import { MutableRefObject } from 'react';
import { MetaTagModel } from '../types';
declare type InstanceConfig = MutableRefObject<MetaTagModel>;
declare type StoreListener = (metas: MetaTagModel) => void;
export declare const addMetasToStore: (instanceConfig: MutableRefObject<MetaTagModel>) => void;
export declare const removeMetasFromStore: (instanceConfig: MutableRefObject<MetaTagModel>) => void;
export declare const addMetasToStore: (instanceConfig: InstanceConfig) => void;
export declare const removeMetasFromStore: (instanceConfig: InstanceConfig) => void;
export declare const clearStore: () => void;

@@ -7,0 +8,0 @@ export declare const subscribeToStore: (listener: StoreListener) => () => void;

{
"name": "react-metatags-hook",
"version": "1.1.2",
"version": "1.2.0",
"description": "React Hook to manage html meta tags",

@@ -34,12 +34,16 @@ "main": "./dist/index.cjs.js",

},
"pre-commit": [
"check:all"
],
"devDependencies": {
"@types/jest": "^24.0.13",
"@types/react": "^16.9.3",
"concurrently": "^4.1.2",
"jest": "^24.8.0",
"majestic": "^1.4.1",
"react": "^16.10.1",
"@types/jest": "^25.2.1",
"@types/react": "^16.9.34",
"concurrently": "^5.1.0",
"jest": "^25.3.0",
"majestic": "^1.6.2",
"pre-commit": "^1.2.2",
"react": "^16.13.1",
"react-hooks-testing-library": "^0.6.0",
"react-test-renderer": "^16.10.1",
"rollup": "^1.21.4",
"react-test-renderer": "^16.13.1",
"rollup": "^2.6.0",
"rollup-plugin-clear": "^2.0.7",

@@ -49,11 +53,11 @@ "rollup-plugin-commonjs": "^10.1.0",

"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-sourcemaps": "^0.4.2",
"rollup-plugin-terser": "^5.1.2",
"rollup-plugin-typescript2": "^0.24.3",
"ts-jest": "^24.0.2",
"tslint": "^5.20.0",
"tslint-config-standard": "^8.0.1",
"tslint-react": "^4.1.0",
"tslint-react-hooks": "^2.2.1",
"typescript": "^3.6.3"
"rollup-plugin-sourcemaps": "^0.5.0",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-typescript2": "^0.27.0",
"ts-jest": "^25.3.1",
"tslint": "^6.1.1",
"tslint-config-standard": "^9.0.0",
"tslint-react": "^4.2.0",
"tslint-react-hooks": "^2.2.2",
"typescript": "^3.8.3"
},

@@ -60,0 +64,0 @@ "peerDependencies": {

@@ -140,14 +140,5 @@ ![npm](https://img.shields.io/npm/v/react-metatags-hook)

## Server Side Rendering
This library exports the function `generateStaticHtml` that can be used to generate an HTML string of the meta tags created by this hook. Use it after `ReactDOMServer.renderToString` or `ReactDOMServer.renderToStaticMarkup`.
```javascript
import { generateStaticHtml } from 'react-metatags-hook'
...
ReactDOMServer.renderToString(<App />);
const metaHTML = generateStaticHtml()
```
## What happens when used in multiple component or one component is unmounted
### Nested and Sibling components
When used in nested components, the meta defined in the children are merged with the ones defined in the parents. If the same meta are defined in both the parent and the children, the children ones take precedence and overwrite parents ones.
When used in nested components, metas defined in the children are merged with the ones defined in the parents. If the same meta are defined in both the parent and the children, children ones take precedence and overwrite parents ones. (see **Tags creation and update** for more details)

@@ -157,17 +148,32 @@ The same logic applies if used in sibling components: the last to render is the one that take precedence if same meta are defined.

### Component unmount
When a component that uses this hook is unmounted, its meta definition are removed from a global list of meta and the meta definition is recalculated based on the definitions in other components. If some meta is not longer present in this resulting definition, the meta tag is removed from the DOM.
When a component that uses this hook is unmounted, its metas definition are removed from a global list of metas and the metas definition is recalculated based on the definitions in other components. If some meta is not longer present in this resulting definition, the meta tag is removed from the DOM.
### How `<meta />` and `<link />` are identified
To identify which `<meta />` and `<link />` are unique (used to merge meta definition as just described, as well as to delete or update the DOM), the following logic is applied.
### Tags creation and update
As just described, this library allows to overwrite tags in nested components, and updates existing tags if possible rather the creating new one.
To do so, it has to identify when two tag definitions refers to the same tag (i.e. you want to change the `<link rel='icon'/>` when a component is mounted).
**meta**
- have the same `name` attribute
- have the same `property` attribute
- have the same `http-equiv` attribute
- have the same `charset` attribute
To identify when tags are unique, the following attributes are considered, and every time at least one of them is different, a new tag in the head is created.
**link**:
- have the same `rel` attribute
- have the same `rel` and `sizes` attribute
**Any Tag**
- `id`
**`<meta />`**
- `name`
- `property`
- `http-equiv`
- `charset`
**`<link />`**
- `rel`
- `sizes`
If this logic is unsatisfactory, please let me know and I'll be happy to improve it.
## Server Side Rendering
This library exports the function `generateStaticHtml` that can be used to generate an HTML string of the meta tags created by this hook. Use it after `ReactDOMServer.renderToString` or `ReactDOMServer.renderToStaticMarkup`.
```javascript
import { generateStaticHtml } from 'react-metatags-hook'
...
ReactDOMServer.renderToString(<App />);
const metaHTML = generateStaticHtml()
```

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc