@americanexpress/react-seo
Advanced tools
Comparing version 1.3.0 to 2.0.0
@@ -6,148 +6,36 @@ "use strict"; | ||
}); | ||
var _exportNames = {}; | ||
exports.default = void 0; | ||
var _react = _interopRequireDefault(require("react")); | ||
var _SEO = _interopRequireDefault(require("./components/SEO")); | ||
var _propTypes = _interopRequireDefault(require("prop-types")); | ||
var _shapes = require("./shapes"); | ||
var _reactHelmet = require("react-helmet"); | ||
Object.keys(_shapes).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function get() { | ||
return _shapes[key]; | ||
} | ||
}); | ||
}); | ||
var _HelmetConstants = require("react-helmet/lib/HelmetConstants"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } | ||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } | ||
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } | ||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } | ||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } | ||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } | ||
var SEO = function SEO(_ref) { | ||
var article = _ref.article, | ||
author = _ref.author, | ||
children = _ref.children, | ||
description = _ref.description, | ||
metaImage = _ref.image, | ||
keywords = _ref.keywords, | ||
lang = _ref.lang, | ||
meta = _ref.meta, | ||
pathname = _ref.pathname, | ||
siteUrl = _ref.siteUrl, | ||
title = _ref.title, | ||
canonicalTag = _ref.canonical, | ||
props = _objectWithoutProperties(_ref, ["article", "author", "children", "description", "image", "keywords", "lang", "meta", "pathname", "siteUrl", "title", "canonical"]); | ||
var image = metaImage && metaImage.src ? "".concat(siteUrl).concat(metaImage.src) : null; | ||
var canonical = canonicalTag || (pathname ? "".concat(siteUrl).concat(pathname) : null); | ||
var link = canonical ? [{ | ||
rel: 'canonical', | ||
href: canonical | ||
}] : []; | ||
var metaTags = [{ | ||
name: 'description', | ||
content: description | ||
}, { | ||
name: 'keywords', | ||
content: keywords.join(',') | ||
}, { | ||
property: 'og:title', | ||
content: title | ||
}, { | ||
property: 'og:description', | ||
content: description | ||
}, { | ||
property: 'og:type', | ||
content: article ? 'article' : 'website' | ||
}, { | ||
name: 'twitter:creator', | ||
content: author | ||
}, { | ||
name: 'twitter:title', | ||
content: title | ||
}, { | ||
name: 'twitter:description', | ||
content: description | ||
}].concat(_toConsumableArray(meta)); | ||
if (metaImage) { | ||
metaTags = [].concat(_toConsumableArray(metaTags), [{ | ||
property: 'og:image', | ||
content: image | ||
}, { | ||
property: 'og:image:width', | ||
content: metaImage.width | ||
}, { | ||
property: 'og:image:height', | ||
content: metaImage.height | ||
}, { | ||
name: 'twitter:card', | ||
content: 'summary_large_image' | ||
}]); | ||
} else { | ||
metaTags = [].concat(_toConsumableArray(metaTags), [{ | ||
name: 'twitter:card', | ||
content: 'summary' | ||
}]); | ||
} | ||
var helmetProps = Object.values(_HelmetConstants.HELMET_PROPS).filter(function (propName) { | ||
return props[propName] !== undefined; | ||
}).reduce(function (result, propName) { | ||
return _objectSpread({}, result, _defineProperty({}, propName, props[propName])); | ||
}, {}); | ||
return _react.default.createElement(_reactHelmet.Helmet, _extends({ | ||
htmlAttributes: { | ||
lang: lang | ||
}, | ||
link: link, | ||
meta: metaTags // eslint-disable-next-line react/jsx-props-no-spreading | ||
}, helmetProps), children); | ||
}; | ||
SEO.propTypes = { | ||
article: _propTypes.default.bool, | ||
author: _propTypes.default.string, | ||
children: _propTypes.default.node, | ||
description: _propTypes.default.string, | ||
image: _propTypes.default.shape({ | ||
src: _propTypes.default.string | ||
}), | ||
keywords: _propTypes.default.arrayOf(_propTypes.default.string), | ||
lang: _propTypes.default.string, | ||
meta: _propTypes.default.arrayOf(_propTypes.default.object), | ||
pathname: _propTypes.default.string, | ||
siteUrl: _propTypes.default.string, | ||
title: _propTypes.default.string, | ||
canonical: _propTypes.default.string | ||
}; | ||
SEO.defaultProps = { | ||
article: false, | ||
author: '', | ||
children: null, | ||
description: '', | ||
image: null, | ||
keywords: [], | ||
lang: 'en-US', | ||
meta: [], | ||
pathname: '', | ||
siteUrl: '', | ||
title: '', | ||
canonical: '' | ||
}; | ||
var _default = SEO; | ||
/* | ||
* Copyright 2020 American Express Travel Related Services Company, Inc. | ||
* | ||
* 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 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express | ||
* or implied. See the License for the specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
var _default = _SEO.default; | ||
exports.default = _default; |
{ | ||
"name": "@americanexpress/react-seo", | ||
"version": "1.3.0", | ||
"version": "2.0.0", | ||
"description": "Simple SEO tag manager for React", | ||
@@ -11,3 +11,3 @@ "main": "build/index.js", | ||
"test:git-history": "commitlint --from origin/master --to HEAD", | ||
"build": "npx babel src --out-dir build", | ||
"build": "babel src --out-dir build", | ||
"clean": "rimraf build", | ||
@@ -51,2 +51,7 @@ "prepublish": "npm run build", | ||
"@commitlint/config-conventional": "^8.3.4", | ||
"@semantic-release/changelog": "^5.0.1", | ||
"@semantic-release/commit-analyzer": "^8.0.1", | ||
"@semantic-release/git": "^9.0.0", | ||
"@semantic-release/npm": "^7.0.5", | ||
"@semantic-release/release-notes-generator": "^9.0.1", | ||
"amex-jest-preset-react": "^5.0.3", | ||
@@ -61,3 +66,4 @@ "babel-preset-amex": "^3.3.0", | ||
"lockfile-lint": "^4.1.0", | ||
"react-dom": "^16.13.1" | ||
"react-dom": "^16.13.1", | ||
"rimraf": "^3.0.2" | ||
}, | ||
@@ -69,2 +75,13 @@ "dependencies": { | ||
}, | ||
"release": { | ||
"plugins": [ | ||
"@semantic-release/commit-analyzer", | ||
"@semantic-release/release-notes-generator", | ||
"@semantic-release/changelog", | ||
"@semantic-release/npm", | ||
"@semantic-release/git", | ||
"@semantic-release/github" | ||
], | ||
"branch": "master" | ||
}, | ||
"husky": { | ||
@@ -71,0 +88,0 @@ "hooks": { |
170
README.md
@@ -28,2 +28,7 @@ <h1 align="center"> | ||
``` | ||
<br /> | ||
Let's start with a minimal example of basic usage: | ||
```javascript | ||
@@ -36,9 +41,64 @@ import React from 'react'; | ||
<SEO | ||
author="John Doe" | ||
title="Lorem Ipsum" | ||
description="Lorem ipsum sat delor." | ||
keywords={['foo', 'bar']} | ||
siteUrl="https://example.com" | ||
siteUrl="http://example.com" | ||
image={{ | ||
src: 'http://example.com/foo.jpg' | ||
}} | ||
/> | ||
</div> | ||
); | ||
export default MyModule; | ||
``` | ||
This will result in the following tags being added to the `head` element: | ||
```html | ||
<head> | ||
<title>Lorem Ipsum</title> | ||
<link rel="canonical" href="http://example.com"> | ||
<meta property="og:url" content="http://example.com"> | ||
<meta property="og:title" content="Lorem Ipsum"> | ||
<meta property="og:description" content="Lorem ispum sat delor."> | ||
<meta property="og:image" content="http://example.com/foo.jpg"> | ||
<meta name="twitter:card" content="summary"> | ||
<meta name="twitter:title" content="Lorem Ipsum"> | ||
<meta name="twitter:description" content="Lorem ispum sat delor."> | ||
<meta name="twitter:image" content="http://example.com/foo.jpg"> | ||
<meta name="description" content="Lorem ispum sat delor."> | ||
<meta name="keywords" content="foo, bar"> | ||
</head> | ||
``` | ||
Notice in the example above that the Open Graph and Twitter Card metadata is constructed from the `title`, `description`, and `image` props. To override these values or add additional tags not provided by default, you may use the `openGraph` and `twitterCard` props. | ||
```javascript | ||
import React from 'react'; | ||
import SEO from '@americanexpress/react-seo'; | ||
const MyModule = () => ( | ||
<div> | ||
<SEO | ||
title="Lorem Ipsum" | ||
image="https://example.com/foo.png" | ||
meta=[{ charset: 'utf-8' }] | ||
description="Lorem ipsum sat delor." | ||
keywords={['foo', 'bar']} | ||
siteUrl="http://example.com" | ||
openGraph={{ | ||
title: 'Facebook Lorem Ipsum', | ||
description: 'Facebook Lorem ipsum sat delor.', | ||
image: { | ||
src: 'http://example.com/facebook-foo.jpg', | ||
alt: 'Lorem ipsum', | ||
} | ||
}} | ||
twitterCard={{ | ||
title: 'Twitter Lorem Ipsum', | ||
description: 'Twitter Lorem ipsum sat delor.', | ||
image: { | ||
src: 'http://example.com/twitter-foo.jpg', | ||
alt: 'Lorem ipsum', | ||
} | ||
}} | ||
/> | ||
@@ -50,2 +110,3 @@ </div> | ||
``` | ||
<br /> | ||
@@ -59,15 +120,92 @@ | ||
SEO.propTypes = { | ||
article: PropTypes.bool, | ||
author: PropTypes.string, | ||
description: PropTypes.string, | ||
image: PropTypes.shape({ | ||
src: PropTypes.string, | ||
title: string, | ||
description: string, | ||
canonical: string, | ||
image: shape({ | ||
src: string, | ||
secureUrl: string, | ||
type: string, | ||
width: number, | ||
height: number, | ||
alt: string, | ||
}), | ||
keywords: PropTypes.arrayOf(PropTypes.string), | ||
locale: PropTypes.string, | ||
meta: PropTypes.arrayOf(PropTypes.object), | ||
pathname: PropTypes.string, | ||
siteUrl: PropTypes.string, | ||
title: PropTypes.string, | ||
canonical: PropTypes.string, | ||
video: shape({ | ||
src: string, | ||
secureUrl: string, | ||
type: string, | ||
width: number, | ||
height: number, | ||
alt: string, | ||
}), | ||
openGraph: shape({ | ||
type: string, | ||
url: string, | ||
title: string, | ||
description: string, | ||
determiner: string, | ||
locale: string, | ||
localeAlternate: string, | ||
siteName: string, | ||
image: shape({ | ||
src: string, | ||
secureUrl: string, | ||
type: string, | ||
width: number, | ||
height: number, | ||
alt: string, | ||
}), | ||
video: shape({ | ||
src: string, | ||
secureUrl: string, | ||
type: string, | ||
width: number, | ||
height: number, | ||
alt: string, | ||
}), | ||
audio: shape({ | ||
src: string, | ||
secureUrl: string, | ||
type: string, | ||
}), | ||
}), | ||
twitterCard: shape({ | ||
card: string, | ||
title: string, | ||
description: string, | ||
image: shape({ | ||
src: string, | ||
alt: string, | ||
}), | ||
site: string, | ||
siteId: string, | ||
creator: string, | ||
creatorId: string, | ||
app: shape({ | ||
country: string, | ||
iphone: shape({ | ||
id: string, | ||
url: string, | ||
name: string, | ||
}), | ||
ipad: shape({ | ||
id: string, | ||
url: string, | ||
name: string, | ||
}), | ||
googlePlay: shape({ | ||
id: string, | ||
url: string, | ||
name: string, | ||
}), | ||
}), | ||
player: shape({ | ||
src: string, | ||
width: number, | ||
height: number, | ||
}), | ||
}), | ||
keywords: arrayOf(string), | ||
locale: string, | ||
meta: arrayOf(object), | ||
siteUrl: string, | ||
}; | ||
@@ -74,0 +212,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51690
23
566
247
21
2