next-seo
Version:
SEO plugin for Next.js projects
1,654 lines (1,606 loc) • 60.9 kB
JavaScript
import React from 'react';
import Head from 'next/head';
function _extends() {
_extends = Object.assign ? Object.assign.bind() : 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 _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;
}
const _excluded$x = ["keyOverride"];
const defaults = {
templateTitle: '',
noindex: false,
nofollow: false,
defaultOpenGraphImageWidth: 0,
defaultOpenGraphImageHeight: 0,
defaultOpenGraphVideoWidth: 0,
defaultOpenGraphVideoHeight: 0
};
const buildOpenGraphMediaTags = (mediaType, media = [], {
defaultWidth,
defaultHeight
} = {}) => {
return media.reduce((tags, medium, index) => {
tags.push( /*#__PURE__*/React.createElement("meta", {
key: `og:${mediaType}:0${index}`,
property: `og:${mediaType}`,
content: medium.url
}));
if (medium.alt) {
tags.push( /*#__PURE__*/React.createElement("meta", {
key: `og:${mediaType}:alt0${index}`,
property: `og:${mediaType}:alt`,
content: medium.alt
}));
}
if (medium.secureUrl) {
tags.push( /*#__PURE__*/React.createElement("meta", {
key: `og:${mediaType}:secure_url0${index}`,
property: `og:${mediaType}:secure_url`,
content: medium.secureUrl.toString()
}));
}
if (medium.type) {
tags.push( /*#__PURE__*/React.createElement("meta", {
key: `og:${mediaType}:type0${index}`,
property: `og:${mediaType}:type`,
content: medium.type.toString()
}));
}
if (medium.width) {
tags.push( /*#__PURE__*/React.createElement("meta", {
key: `og:${mediaType}:width0${index}`,
property: `og:${mediaType}:width`,
content: medium.width.toString()
}));
} else if (defaultWidth) {
tags.push( /*#__PURE__*/React.createElement("meta", {
key: `og:${mediaType}:width0${index}`,
property: `og:${mediaType}:width`,
content: defaultWidth.toString()
}));
}
if (medium.height) {
tags.push( /*#__PURE__*/React.createElement("meta", {
key: `og:${mediaType}:height${index}`,
property: `og:${mediaType}:height`,
content: medium.height.toString()
}));
} else if (defaultHeight) {
tags.push( /*#__PURE__*/React.createElement("meta", {
key: `og:${mediaType}:height${index}`,
property: `og:${mediaType}:height`,
content: defaultHeight.toString()
}));
}
return tags;
}, []);
};
const buildTags = config => {
var _config$openGraph, _config$openGraph3, _config$additionalLin;
const tagsToRender = [];
if (config.titleTemplate) {
defaults.templateTitle = config.titleTemplate;
}
let updatedTitle = '';
if (config.title) {
updatedTitle = config.title;
if (defaults.templateTitle) {
updatedTitle = defaults.templateTitle.replace(/%s/g, () => updatedTitle);
}
} else if (config.defaultTitle) {
updatedTitle = config.defaultTitle;
}
if (updatedTitle) {
tagsToRender.push( /*#__PURE__*/React.createElement("title", {
key: "title"
}, updatedTitle));
}
const noindex = config.noindex || defaults.noindex || config.dangerouslySetAllPagesToNoIndex;
const nofollow = config.nofollow || defaults.nofollow || config.dangerouslySetAllPagesToNoFollow;
let robotsParams = '';
if (config.robotsProps) {
const {
nosnippet,
maxSnippet,
maxImagePreview,
maxVideoPreview,
noarchive,
noimageindex,
notranslate,
unavailableAfter
} = config.robotsProps;
robotsParams = `${nosnippet ? ',nosnippet' : ''}${maxSnippet ? `,max-snippet:${maxSnippet}` : ''}${maxImagePreview ? `,max-image-preview:${maxImagePreview}` : ''}${noarchive ? ',noarchive' : ''}${unavailableAfter ? `,unavailable_after:${unavailableAfter}` : ''}${noimageindex ? ',noimageindex' : ''}${maxVideoPreview ? `,max-video-preview:${maxVideoPreview}` : ''}${notranslate ? ',notranslate' : ''}`;
}
if (noindex || nofollow) {
if (config.dangerouslySetAllPagesToNoIndex) {
defaults.noindex = true;
}
if (config.dangerouslySetAllPagesToNoFollow) {
defaults.nofollow = true;
}
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "robots",
name: "robots",
content: `${noindex ? 'noindex' : 'index'},${nofollow ? 'nofollow' : 'follow'}${robotsParams}`
}));
} else {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "robots",
name: "robots",
content: `index,follow${robotsParams}`
}));
}
if (config.description) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "description",
name: "description",
content: config.description
}));
}
if (config.themeColor) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "theme-color",
name: "theme-color",
content: config.themeColor
}));
}
if (config.mobileAlternate) {
tagsToRender.push( /*#__PURE__*/React.createElement("link", {
rel: "alternate",
key: "mobileAlternate",
media: config.mobileAlternate.media,
href: config.mobileAlternate.href
}));
}
if (config.languageAlternates && config.languageAlternates.length > 0) {
config.languageAlternates.forEach(languageAlternate => {
tagsToRender.push( /*#__PURE__*/React.createElement("link", {
rel: "alternate",
key: `languageAlternate-${languageAlternate.hrefLang}`,
hrefLang: languageAlternate.hrefLang,
href: languageAlternate.href
}));
});
}
if (config.twitter) {
if (config.twitter.cardType) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "twitter:card",
name: "twitter:card",
content: config.twitter.cardType
}));
}
if (config.twitter.site) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "twitter:site",
name: "twitter:site",
content: config.twitter.site
}));
}
if (config.twitter.handle) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "twitter:creator",
name: "twitter:creator",
content: config.twitter.handle
}));
}
}
if (config.facebook) {
if (config.facebook.appId) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "fb:app_id",
property: "fb:app_id",
content: config.facebook.appId
}));
}
}
if ((_config$openGraph = config.openGraph) != null && _config$openGraph.title || updatedTitle) {
var _config$openGraph2;
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "og:title",
property: "og:title",
content: ((_config$openGraph2 = config.openGraph) == null ? void 0 : _config$openGraph2.title) || updatedTitle
}));
}
if ((_config$openGraph3 = config.openGraph) != null && _config$openGraph3.description || config.description) {
var _config$openGraph4;
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "og:description",
property: "og:description",
content: ((_config$openGraph4 = config.openGraph) == null ? void 0 : _config$openGraph4.description) || config.description
}));
}
if (config.openGraph) {
if (config.openGraph.url || config.canonical) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "og:url",
property: "og:url",
content: config.openGraph.url || config.canonical
}));
}
if (config.openGraph.type) {
const type = config.openGraph.type.toLowerCase();
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "og:type",
property: "og:type",
content: type
}));
if (type === 'profile' && config.openGraph.profile) {
if (config.openGraph.profile.firstName) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "profile:first_name",
property: "profile:first_name",
content: config.openGraph.profile.firstName
}));
}
if (config.openGraph.profile.lastName) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "profile:last_name",
property: "profile:last_name",
content: config.openGraph.profile.lastName
}));
}
if (config.openGraph.profile.username) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "profile:username",
property: "profile:username",
content: config.openGraph.profile.username
}));
}
if (config.openGraph.profile.gender) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "profile:gender",
property: "profile:gender",
content: config.openGraph.profile.gender
}));
}
} else if (type === 'book' && config.openGraph.book) {
if (config.openGraph.book.authors && config.openGraph.book.authors.length) {
config.openGraph.book.authors.forEach((author, index) => {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: `book:author:0${index}`,
property: "book:author",
content: author
}));
});
}
if (config.openGraph.book.isbn) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "book:isbn",
property: "book:isbn",
content: config.openGraph.book.isbn
}));
}
if (config.openGraph.book.releaseDate) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "book:release_date",
property: "book:release_date",
content: config.openGraph.book.releaseDate
}));
}
if (config.openGraph.book.tags && config.openGraph.book.tags.length) {
config.openGraph.book.tags.forEach((tag, index) => {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: `book:tag:0${index}`,
property: "book:tag",
content: tag
}));
});
}
} else if (type === 'article' && config.openGraph.article) {
if (config.openGraph.article.publishedTime) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "article:published_time",
property: "article:published_time",
content: config.openGraph.article.publishedTime
}));
}
if (config.openGraph.article.modifiedTime) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "article:modified_time",
property: "article:modified_time",
content: config.openGraph.article.modifiedTime
}));
}
if (config.openGraph.article.expirationTime) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "article:expiration_time",
property: "article:expiration_time",
content: config.openGraph.article.expirationTime
}));
}
if (config.openGraph.article.authors && config.openGraph.article.authors.length) {
config.openGraph.article.authors.forEach((author, index) => {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: `article:author:0${index}`,
property: "article:author",
content: author
}));
});
}
if (config.openGraph.article.section) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "article:section",
property: "article:section",
content: config.openGraph.article.section
}));
}
if (config.openGraph.article.tags && config.openGraph.article.tags.length) {
config.openGraph.article.tags.forEach((tag, index) => {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: `article:tag:0${index}`,
property: "article:tag",
content: tag
}));
});
}
} else if ((type === 'video.movie' || type === 'video.episode' || type === 'video.tv_show' || type === 'video.other') && config.openGraph.video) {
if (config.openGraph.video.actors && config.openGraph.video.actors.length) {
config.openGraph.video.actors.forEach((actor, index) => {
if (actor.profile) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: `video:actor:0${index}`,
property: "video:actor",
content: actor.profile
}));
}
if (actor.role) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: `video:actor:role:0${index}`,
property: "video:actor:role",
content: actor.role
}));
}
});
}
if (config.openGraph.video.directors && config.openGraph.video.directors.length) {
config.openGraph.video.directors.forEach((director, index) => {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: `video:director:0${index}`,
property: "video:director",
content: director
}));
});
}
if (config.openGraph.video.writers && config.openGraph.video.writers.length) {
config.openGraph.video.writers.forEach((writer, index) => {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: `video:writer:0${index}`,
property: "video:writer",
content: writer
}));
});
}
if (config.openGraph.video.duration) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "video:duration",
property: "video:duration",
content: config.openGraph.video.duration.toString()
}));
}
if (config.openGraph.video.releaseDate) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "video:release_date",
property: "video:release_date",
content: config.openGraph.video.releaseDate
}));
}
if (config.openGraph.video.tags && config.openGraph.video.tags.length) {
config.openGraph.video.tags.forEach((tag, index) => {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: `video:tag:0${index}`,
property: "video:tag",
content: tag
}));
});
}
if (config.openGraph.video.series) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "video:series",
property: "video:series",
content: config.openGraph.video.series
}));
}
}
}
// images
if (config.defaultOpenGraphImageWidth) {
defaults.defaultOpenGraphImageWidth = config.defaultOpenGraphImageWidth;
}
if (config.defaultOpenGraphImageHeight) {
defaults.defaultOpenGraphImageHeight = config.defaultOpenGraphImageHeight;
}
if (config.openGraph.images && config.openGraph.images.length) {
tagsToRender.push(...buildOpenGraphMediaTags('image', config.openGraph.images, {
defaultWidth: defaults.defaultOpenGraphImageWidth,
defaultHeight: defaults.defaultOpenGraphImageHeight
}));
}
// videos
if (config.defaultOpenGraphVideoWidth) {
defaults.defaultOpenGraphVideoWidth = config.defaultOpenGraphVideoWidth;
}
if (config.defaultOpenGraphVideoHeight) {
defaults.defaultOpenGraphVideoHeight = config.defaultOpenGraphVideoHeight;
}
if (config.openGraph.videos && config.openGraph.videos.length) {
tagsToRender.push(...buildOpenGraphMediaTags('video', config.openGraph.videos, {
defaultWidth: defaults.defaultOpenGraphVideoWidth,
defaultHeight: defaults.defaultOpenGraphVideoHeight
}));
}
// audio
if (config.openGraph.audio) {
tagsToRender.push(...buildOpenGraphMediaTags('audio', config.openGraph.audio));
}
if (config.openGraph.locale) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "og:locale",
property: "og:locale",
content: config.openGraph.locale
}));
}
if (config.openGraph.siteName || config.openGraph.site_name) {
tagsToRender.push( /*#__PURE__*/React.createElement("meta", {
key: "og:site_name",
property: "og:site_name",
content: config.openGraph.siteName || config.openGraph.site_name
}));
}
}
if (config.canonical) {
tagsToRender.push( /*#__PURE__*/React.createElement("link", {
rel: "canonical",
href: config.canonical,
key: "canonical"
}));
}
if (config.additionalMetaTags && config.additionalMetaTags.length > 0) {
config.additionalMetaTags.forEach(_ref => {
var _ref2, _ref3;
let {
keyOverride
} = _ref,
tag = _objectWithoutPropertiesLoose(_ref, _excluded$x);
tagsToRender.push( /*#__PURE__*/React.createElement("meta", _extends({
key: `meta:${(_ref2 = (_ref3 = keyOverride != null ? keyOverride : tag.name) != null ? _ref3 : tag.property) != null ? _ref2 : tag.httpEquiv}`
}, tag)));
});
}
if ((_config$additionalLin = config.additionalLinkTags) != null && _config$additionalLin.length) {
config.additionalLinkTags.forEach(tag => {
var _tag$keyOverride;
tagsToRender.push( /*#__PURE__*/React.createElement("link", _extends({
key: `link${(_tag$keyOverride = tag.keyOverride) != null ? _tag$keyOverride : tag.href}${tag.rel}`
}, tag)));
});
}
return tagsToRender;
};
const WithHead = props => {
return /*#__PURE__*/React.createElement(Head, null, buildTags(props));
};
const DefaultSeo = ({
title,
titleTemplate,
defaultTitle,
themeColor,
dangerouslySetAllPagesToNoIndex: _dangerouslySetAllPagesToNoIndex = false,
dangerouslySetAllPagesToNoFollow: _dangerouslySetAllPagesToNoFollow = false,
description,
canonical,
facebook,
openGraph,
additionalMetaTags,
twitter,
defaultOpenGraphImageWidth,
defaultOpenGraphImageHeight,
defaultOpenGraphVideoWidth,
defaultOpenGraphVideoHeight,
mobileAlternate,
languageAlternates,
additionalLinkTags,
robotsProps
}) => {
return /*#__PURE__*/React.createElement(WithHead, {
title: title,
titleTemplate: titleTemplate,
defaultTitle: defaultTitle,
themeColor: themeColor,
dangerouslySetAllPagesToNoIndex: _dangerouslySetAllPagesToNoIndex,
dangerouslySetAllPagesToNoFollow: _dangerouslySetAllPagesToNoFollow,
description: description,
canonical: canonical,
facebook: facebook,
openGraph: openGraph,
additionalMetaTags: additionalMetaTags,
twitter: twitter,
defaultOpenGraphImageWidth: defaultOpenGraphImageWidth,
defaultOpenGraphImageHeight: defaultOpenGraphImageHeight,
defaultOpenGraphVideoWidth: defaultOpenGraphVideoWidth,
defaultOpenGraphVideoHeight: defaultOpenGraphVideoHeight,
mobileAlternate: mobileAlternate,
languageAlternates: languageAlternates,
additionalLinkTags: additionalLinkTags,
robotsProps: robotsProps
});
};
const NextSeo = ({
title,
themeColor,
noindex: _noindex = false,
nofollow,
robotsProps,
description,
canonical,
openGraph,
facebook,
twitter,
additionalMetaTags,
titleTemplate,
defaultTitle,
mobileAlternate,
languageAlternates,
additionalLinkTags,
useAppDir: _useAppDir = false
}) => {
return /*#__PURE__*/React.createElement(React.Fragment, null, _useAppDir ? buildTags({
title,
themeColor,
noindex: _noindex,
nofollow,
robotsProps,
description,
canonical,
facebook,
openGraph,
additionalMetaTags,
twitter,
titleTemplate,
defaultTitle,
mobileAlternate,
languageAlternates,
additionalLinkTags
}) : /*#__PURE__*/React.createElement(WithHead, {
title: title,
themeColor: themeColor,
noindex: _noindex,
nofollow: nofollow,
robotsProps: robotsProps,
description: description,
canonical: canonical,
facebook: facebook,
openGraph: openGraph,
additionalMetaTags: additionalMetaTags,
twitter: twitter,
titleTemplate: titleTemplate,
defaultTitle: defaultTitle,
mobileAlternate: mobileAlternate,
languageAlternates: languageAlternates,
additionalLinkTags: additionalLinkTags
}));
};
const toJson = (type, jsonld) => {
let data = jsonld;
if (Array.isArray(data) && data.length === 1) {
data = _extends({}, jsonld[0]);
}
const jsonLdObject = Array.isArray(data) ? data.map(item => formatObjectForSchema(type, item)) : formatObjectForSchema(type, data);
return {
__html: JSON.stringify(jsonLdObject, safeJsonLdReplacer)
};
};
const formatObjectForSchema = (type, jsonld) => {
const {
id = undefined
} = jsonld;
const updated = _extends({}, id ? {
'@id': jsonld.id
} : {}, jsonld);
delete updated.id;
return _extends({
'@context': 'https://schema.org',
'@type': type
}, updated);
};
const ESCAPE_ENTITIES = Object.freeze({
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
});
const ESCAPE_REGEX = new RegExp(`[${Object.keys(ESCAPE_ENTITIES).join('')}]`, 'g');
const ESCAPE_REPLACER = t => ESCAPE_ENTITIES[t];
/**
* A replacer for JSON.stringify to strip JSON-LD of illegal HTML entities
* per https://www.w3.org/TR/json-ld11/#restrictions-for-contents-of-json-ld-script-elements
*/
const safeJsonLdReplacer = (() => {
// Replace per https://www.w3.org/TR/json-ld11/#restrictions-for-contents-of-json-ld-script-elements
// Solution from https://stackoverflow.com/a/5499821/864313
return (_, value) => {
switch (typeof value) {
case 'object':
// Omit null values.
if (value === null) {
return undefined;
}
return value;
// JSON.stringify will recursively call replacer.
case 'number':
case 'boolean':
case 'bigint':
return value;
// These values are not risky.
case 'string':
return value.replace(ESCAPE_REGEX, ESCAPE_REPLACER);
default:
{
// JSON.stringify will remove this element.
return undefined;
}
}
};
})();
const _excluded$w = ["type", "keyOverride", "scriptKey", "scriptId", "dataArray", "useAppDir"];
function JsonLd(_ref) {
let {
type = 'Thing',
keyOverride,
scriptKey,
scriptId = undefined,
dataArray,
useAppDir = false
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$w);
const JsonLdScript = () => /*#__PURE__*/React.createElement("script", {
type: "application/ld+json",
id: scriptId,
"data-testid": scriptId,
dangerouslySetInnerHTML: toJson(type, dataArray === undefined ? _extends({}, rest) : dataArray),
key: `jsonld-${scriptKey}${keyOverride ? `-${keyOverride}` : ''}`
});
if (useAppDir) {
return /*#__PURE__*/React.createElement(JsonLdScript, null);
}
return /*#__PURE__*/React.createElement(Head, null, JsonLdScript());
}
/**
* Generate author information
* @param author
* @returns
*/
function generateAuthorInfo(author) {
if (typeof author === 'string') {
return {
'@type': 'Person',
name: author
};
} else if (!!author.name) {
var _author$type;
return {
'@type': (_author$type = author == null ? void 0 : author.type) != null ? _author$type : 'Person',
name: author.name,
url: author == null ? void 0 : author.url
};
}
return;
}
function setAuthor(author) {
if (Array.isArray(author)) {
return author.map(item => generateAuthorInfo(item)).filter(item => !!item);
} else if (author) {
return generateAuthorInfo(author);
}
return;
}
function setImage(image) {
if (image) {
return {
'@type': 'ImageObject',
url: image
};
}
return undefined;
}
function setPublisher(publisherName, publisherLogo) {
if (!publisherName) {
return undefined;
}
return {
'@type': 'Organization',
name: publisherName,
logo: setImage(publisherLogo)
};
}
function setReviewRating(rating) {
if (rating) {
return _extends({}, rating, {
'@type': 'Rating'
});
}
return undefined;
}
const _excluded$v = ["reviewRating", "author", "publisher"];
function setReviews(reviews) {
function mapReview(_ref) {
let {
reviewRating,
author,
publisher
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$v);
return _extends({}, rest, {
'@type': 'Review'
}, author && {
author: setAuthor(author)
}, reviewRating && {
reviewRating: setReviewRating(reviewRating)
}, publisher && {
publisher: setPublisher(publisher.name)
});
}
if (Array.isArray(reviews)) {
return reviews.map(mapReview);
} else if (reviews) {
return mapReview(reviews);
}
return undefined;
}
function setNutrition(calories) {
if (calories) {
return {
'@type': 'NutritionInformation',
calories: `${calories} calories`
};
}
return undefined;
}
function setAggregateRating(aggregateRating) {
if (aggregateRating) {
return {
'@type': 'AggregateRating',
ratingCount: aggregateRating.ratingCount,
reviewCount: aggregateRating.reviewCount,
bestRating: aggregateRating.bestRating,
ratingValue: aggregateRating.ratingValue
};
}
return undefined;
}
function setClip(clips) {
function mapClip(clip) {
return _extends({}, clip, {
'@type': 'Clip'
});
}
if (Array.isArray(clips)) {
return clips.map(mapClip);
} else if (clips) {
return mapClip(clips);
}
return undefined;
}
function setInteractionStatistic(watchCount) {
if (watchCount) {
return {
'@type': 'InteractionCounter',
interactionType: 'https://schema.org/WatchAction',
userInteractionCount: watchCount
};
}
return undefined;
}
function setBroadcastEvent(publication) {
function mapBroadcastEvent(publication) {
return _extends({}, publication, {
'@type': 'BroadcastEvent'
});
}
if (publication) {
if (Array.isArray(publication)) {
return publication.map(mapBroadcastEvent);
}
return mapBroadcastEvent(publication);
}
return undefined;
}
const _excluded$u = ["thumbnailUrls", "hasPart", "watchCount", "publication"];
function setVideo(video, setContext = false) {
function mapVideo(_ref, context) {
let {
thumbnailUrls,
hasPart,
watchCount,
publication
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$u);
return _extends({}, rest, {
'@type': 'VideoObject'
}, context && {
'@context': 'https://schema.org'
}, {
thumbnailUrl: thumbnailUrls,
hasPart: setClip(hasPart),
interactionStatistic: setInteractionStatistic(watchCount),
publication: setBroadcastEvent(publication)
});
}
if (video) {
return mapVideo(video, setContext);
}
return undefined;
}
function setInstruction(instruction) {
if (instruction) {
return _extends({}, instruction, {
'@type': 'HowToStep'
});
}
return undefined;
}
const _excluded$t = ["type", "keyOverride", "ofType", "data"],
_excluded2$1 = ["authorName", "images", "yields", "category", "calories", "aggregateRating", "video", "ingredients", "instructions", "cuisine"];
function CarouselJsonLd(_ref) {
let {
type = 'Carousel',
keyOverride,
ofType,
data
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$t);
function generateList(data, ofType) {
switch (ofType) {
case 'default':
return data.map((item, index) => ({
'@type': 'ListItem',
position: `${index + 1}`,
url: item.url
}));
case 'course':
return data.map((item, index) => ({
'@type': 'ListItem',
position: `${index + 1}`,
item: {
'@context': 'https://schema.org',
'@type': 'Course',
url: item.url,
name: item.courseName,
description: item.description,
provider: {
'@type': 'Organization',
name: item.providerName,
sameAs: item.providerUrl
}
}
}));
case 'movie':
return data.map((item, index) => ({
'@type': 'ListItem',
position: `${index + 1}`,
item: {
'@context': 'https://schema.org',
'@type': 'Movie',
name: item.name,
url: item.url,
image: item.image,
dateCreated: item.dateCreated,
director: item.director ? Array.isArray(item.director) ? item.director.map(director => ({
'@type': 'Person',
name: director.name
})) : {
'@type': 'Person',
name: item.director.name
} : undefined,
review: setReviews(item.review)
}
}));
case 'recipe':
return data.map((_ref2, index) => {
let {
authorName,
images,
yields,
category,
calories,
aggregateRating,
video,
ingredients,
instructions,
cuisine
} = _ref2,
rest = _objectWithoutPropertiesLoose(_ref2, _excluded2$1);
return {
'@type': 'ListItem',
position: `${index + 1}`,
item: _extends({
'@context': 'https://schema.org',
'@type': 'Recipe'
}, rest, {
author: setAuthor(authorName),
image: images,
recipeYield: yields,
recipeCategory: category,
recipeCuisine: cuisine,
nutrition: setNutrition(calories),
aggregateRating: setAggregateRating(aggregateRating),
video: setVideo(video),
recipeIngredient: ingredients,
recipeInstructions: instructions.map(setInstruction)
})
};
});
}
}
const jsonLdData = _extends({
'@type': 'ItemList',
itemListElement: generateList(data, ofType)
}, rest);
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, jsonLdData, {
scriptKey: "Carousel"
}));
}
const _excluded$s = ["type", "keyOverride", "url", "title", "images", "section", "dateCreated", "datePublished", "dateModified", "authorName", "authorType", "publisherName", "publisherLogo", "body", "isAccessibleForFree"];
function NewsArticleJsonLd(_ref) {
let {
type = 'NewsArticle',
keyOverride,
url,
title,
images,
section,
dateCreated,
datePublished,
dateModified,
authorName,
publisherName,
publisherLogo,
body,
isAccessibleForFree
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$s);
const data = _extends({}, rest, {
mainEntityOfPage: {
'@type': 'WebPage',
'@id': url
},
headline: title,
image: images,
articleSection: section,
dateCreated: dateCreated || datePublished,
datePublished: datePublished,
dateModified: dateModified || datePublished,
author: setAuthor(authorName),
publisher: setPublisher(publisherName, publisherLogo),
articleBody: body,
isAccessibleForFree: isAccessibleForFree
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "NewsArticle"
}));
}
const _excluded$r = ["type", "keyOverride", "baseSalary", "hiringOrganization", "applicantLocationRequirements", "experienceRequirements", "jobLocation"];
function JobPostingJsonLd(_ref) {
let {
type = 'JobPosting',
keyOverride,
baseSalary,
hiringOrganization,
applicantLocationRequirements,
experienceRequirements,
jobLocation
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$r);
function setBaseSalary(baseSalary) {
if (baseSalary) {
return {
'@type': 'MonetaryAmount',
currency: baseSalary.currency,
value: _extends({
'@type': 'QuantitativeValue',
unitText: baseSalary.unitText
}, Array.isArray(baseSalary.value) ? {
minValue: baseSalary.value[0],
maxValue: baseSalary.value[1]
} : {
value: baseSalary.value
})
};
}
return undefined;
}
function setHiringOrganization(org) {
return {
'@type': 'Organization',
name: org.name,
sameAs: org.sameAs,
logo: org.logo
};
}
function setJobLocation(location) {
if (location) {
return {
'@type': 'Place',
address: {
'@type': 'PostalAddress',
addressCountry: location.addressCountry,
addressLocality: location.addressLocality,
addressRegion: location.addressRegion,
postalCode: location.postalCode,
streetAddress: location.streetAddress
}
};
}
return undefined;
}
function setApplicantLocationRequirements(requirements) {
if (requirements) {
return {
'@type': 'Country',
name: requirements
};
}
return undefined;
}
function setOccupationalExperienceRequirements(requirements) {
if (requirements) {
return {
'@type': requirements['@type'] ? requirements['@type'] : 'OccupationalExperienceRequirements',
monthsOfExperience: requirements.minimumMonthsOfExperience
};
}
return undefined;
}
function setEducationalOccupationalCredential(requirements) {
if (requirements) {
return {
'@type': requirements['@type'] ? requirements['@type'] : 'EducationalOccupationalCredential',
credentialCategory: requirements.credentialCategory
};
}
return undefined;
}
const data = _extends({}, rest, {
baseSalary: setBaseSalary(baseSalary),
hiringOrganization: setHiringOrganization(hiringOrganization),
jobLocation: setJobLocation(jobLocation),
applicantLocationRequirements: setApplicantLocationRequirements(applicantLocationRequirements),
experienceRequirements: setOccupationalExperienceRequirements(experienceRequirements == null ? void 0 : experienceRequirements.occupational),
educationRequirements: setEducationalOccupationalCredential(experienceRequirements == null ? void 0 : experienceRequirements.educational),
experienceInPlaceOfEducation: experienceRequirements == null ? void 0 : experienceRequirements.experienceInPlaceOfEducation
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "JobPosting"
}));
}
function setAddress(address) {
if (!address) return undefined;
if (!Array.isArray(address)) return toPostalAddress(address);
// If array of one address, replace with single address
if (address.length === 1) return toPostalAddress(address[0]);
// If array, return mapped array of PostalAddresses
return address.map(toPostalAddress);
}
function toPostalAddress(address) {
if (typeof address === 'string') return address;
return _extends({
'@type': 'PostalAddress'
}, address);
}
function setGeo(geo) {
if (geo) {
return _extends({}, geo, {
'@type': 'GeoCoordinates'
});
}
return undefined;
}
function setAction(action) {
if (action) {
return {
'@type': action.actionType,
name: action.actionName,
target: action.target
};
}
return undefined;
}
function setGeoCircle(geoCircle) {
if (geoCircle) {
return {
'@type': 'GeoCircle',
geoMidpoint: {
'@type': 'GeoCoordinates',
latitude: geoCircle.geoMidpoint.latitude,
longitude: geoCircle.geoMidpoint.longitude
},
geoRadius: geoCircle.geoRadius
};
}
return undefined;
}
function setOffer(offer) {
function setPriceSpecification(priceSpecification) {
if (priceSpecification) {
return {
'@type': priceSpecification.type,
priceCurrency: priceSpecification.priceCurrency,
price: priceSpecification.price
};
}
return undefined;
}
function setItemOffered(itemOffered) {
if (itemOffered) {
return _extends({}, itemOffered, {
'@type': 'Service'
});
}
return undefined;
}
if (offer) {
return _extends({}, offer, {
'@type': 'Offer',
priceSpecification: setPriceSpecification(offer.priceSpecification),
itemOffered: setItemOffered(offer.itemOffered)
});
}
return undefined;
}
function setOpeningHours(openingHours) {
if (openingHours) {
return _extends({}, openingHours, {
'@type': 'OpeningHoursSpecification'
});
}
return undefined;
}
const _excluded$q = ["type", "keyOverride", "address", "geo", "rating", "review", "action", "areaServed", "makesOffer", "openingHours", "images"];
function LocalBusinessJsonLd(_ref) {
let {
type = 'LocalBusiness',
keyOverride,
address,
geo,
rating,
review,
action,
areaServed,
makesOffer,
openingHours,
images
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$q);
const data = _extends({}, rest, {
image: images,
address: setAddress(address),
geo: setGeo(geo),
aggregateRating: setAggregateRating(rating),
review: setReviews(review),
potentialAction: setAction(action),
areaServed: areaServed && areaServed.map(setGeoCircle),
makesOffer: makesOffer == null ? void 0 : makesOffer.map(setOffer),
openingHoursSpecification: Array.isArray(openingHours) ? openingHours.map(setOpeningHours) : setOpeningHours(openingHours)
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "LocalBusiness"
}));
}
const _excluded$p = ["type", "keyOverride", "mainEntity"],
_excluded2 = ["upvoteCount"];
function QAPageJsonLd(_ref) {
var _mainEntity$author, _mainEntity$acceptedA, _mainEntity$acceptedA2;
let {
type = 'QAPage',
keyOverride,
mainEntity
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$p);
const data = _extends({}, rest, {
mainEntity: _extends({}, mainEntity, {
'@type': 'Question',
author: setAuthor((_mainEntity$author = mainEntity.author) == null ? void 0 : _mainEntity$author.name)
}, mainEntity.acceptedAnswer && {
acceptedAnswer: _extends({}, mainEntity.acceptedAnswer, {
'@type': 'Answer',
author: setAuthor((_mainEntity$acceptedA = mainEntity.acceptedAnswer) == null ? void 0 : (_mainEntity$acceptedA2 = _mainEntity$acceptedA.author) == null ? void 0 : _mainEntity$acceptedA2.name)
})
}, mainEntity.suggestedAnswer && {
suggestedAnswer: mainEntity.suggestedAnswer.map(_ref2 => {
var _rest$author;
let {
upvoteCount
} = _ref2,
rest = _objectWithoutPropertiesLoose(_ref2, _excluded2);
return _extends({}, rest, {
'@type': 'Answer',
upvoteCount: upvoteCount || 0,
author: setAuthor((_rest$author = rest.author) == null ? void 0 : _rest$author.name)
});
})
})
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "QAPage"
}));
}
function setItemListElements(items) {
if (items && items.length) {
return items.map(item => ({
'@type': 'ListItem',
position: item.position,
item: {
'@id': item.item,
name: item.name
}
}));
}
return undefined;
}
const _excluded$o = ["type", "keyOverride", "breadcrumb"];
function ProfilePageJsonLd(_ref) {
let {
type = 'ProfilePage',
keyOverride,
breadcrumb
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$o);
const data = _extends({}, rest, {
breadcrumb: Array.isArray(breadcrumb) ? {
'@type': 'BreadcrumbList',
itemListElement: setItemListElements(breadcrumb)
} : breadcrumb
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "ProfilePage"
}));
}
const _excluded$n = ["type", "keyOverride", "potentialActions"];
function SiteLinksSearchBoxJsonLd(_ref) {
let {
type = 'WebSite',
keyOverride,
potentialActions
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$n);
function setPotentialAction(action) {
if (action) {
const {
target,
queryInput
} = action;
return {
'@type': 'SearchAction',
target: `${target}={${queryInput}}`,
'query-input': `required name=${queryInput}`
};
}
return undefined;
}
const data = _extends({}, rest, {
potentialAction: potentialActions.map(setPotentialAction)
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "jsonld-siteLinksSearchBox"
}));
}
const _excluded$m = ["type", "keyOverride", "authorName", "images", "yields", "category", "cuisine", "calories", "aggregateRating", "video", "ingredients", "instructions"];
function RecipeJsonLd(_ref) {
let {
type = 'Recipe',
keyOverride,
authorName,
images,
yields,
category,
cuisine,
calories,
aggregateRating,
video,
ingredients,
instructions
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$m);
const data = _extends({}, rest, {
author: setAuthor(authorName),
image: images,
recipeYield: yields,
recipeCategory: category,
recipeCuisine: cuisine,
nutrition: setNutrition(calories),
aggregateRating: setAggregateRating(aggregateRating),
video: setVideo(video),
recipeIngredient: ingredients,
recipeInstructions: instructions ? instructions.map(setInstruction) : undefined
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "recipe"
}));
}
function setLocation(location) {
if (!location) {
return undefined;
}
if (typeof location === 'string') {
return location;
}
if ('url' in location) {
return setVirtualLocation(location);
} else {
return setPlace(location);
}
}
function setVirtualLocation(location) {
return _extends({}, location, {
'@type': 'VirtualLocation'
});
}
function setPlace(location) {
return _extends({}, location, {
address: setAddress(location.address),
'@type': 'Place'
});
}
const _excluded$l = ["type"];
function setPerformer(performer) {
if (performer) {
const {
type
} = performer,
restPerformer = _objectWithoutPropertiesLoose(performer, _excluded$l);
return _extends({}, restPerformer, {
'@type': type || 'PerformingGroup'
});
}
return undefined;
}
const _excluded$k = ["seller"];
function setOffers(offers) {
function mapOffer(_ref) {
let {
seller
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$k);
return _extends({}, rest, {
'@type': 'Offer'
}, seller && {
seller: {
'@type': 'Organization',
name: seller.name
}
});
}
if (Array.isArray(offers)) {
return offers.map(mapOffer);
} else if (offers) {
return mapOffer(offers);
}
return undefined;
}
function setAggregateOffer(aggregateOffer) {
if (aggregateOffer) {
return {
'@type': 'AggregateOffer',
priceCurrency: aggregateOffer.priceCurrency,
highPrice: aggregateOffer.highPrice,
lowPrice: aggregateOffer.lowPrice,
offerCount: aggregateOffer.offerCount,
offers: setOffers(aggregateOffer.offers)
};
}
return undefined;
}
const _excluded$j = ["type"];
function setOrganizer(organizer) {
if (organizer) {
const {
type
} = organizer,
restOrganizer = _objectWithoutPropertiesLoose(organizer, _excluded$j);
return _extends({}, restOrganizer, {
'@type': type || 'Person'
});
}
return undefined;
}
const _excluded$i = ["type", "keyOverride", "location", "images", "offers", "aggregateOffer", "performers", "organizer", "eventStatus", "eventAttendanceMode"];
function EventJsonLd(_ref) {
let {
type = 'Event',
keyOverride,
location,
images,
offers,
aggregateOffer,
performers,
organizer,
eventStatus,
eventAttendanceMode
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$i);
const data = _extends({}, rest, {
location: setLocation(location),
image: images,
offers: offers ? setOffers(offers) : setAggregateOffer(aggregateOffer),
performer: Array.isArray(performers) ? performers.map(setPerformer) : setPerformer(performers),
organizer: Array.isArray(organizer) ? organizer.map(setOrganizer) : setOrganizer(organizer),
eventStatus: eventStatus ? `https://schema.org/${eventStatus}` : undefined,
eventAttendanceMode: eventAttendanceMode ? `https://schema.org/${eventAttendanceMode}` : undefined
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "Event"
}));
}
function setContactPoint(contactPoint) {
if (contactPoint) {
return _extends({}, contactPoint, {
'@type': 'ContactPoint'
});
}
return undefined;
}
const _excluded$h = ["type", "keyOverride", "contactPoint"];
function CorporateContactJsonLd(_ref) {
let {
type = 'Organization',
keyOverride,
contactPoint
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$h);
const data = _extends({}, rest, {
contactPoint: contactPoint.map(setContactPoint)
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "CorporateContact"
}));
}
function setCreativeWork(creativeWork) {
if (creativeWork) {
return _extends({}, creativeWork, {
'@type': 'CreativeWork'
});
}
return undefined;
}
const _excluded$g = ["type", "keyOverride", "hasPart"];
function CollectionPageJsonLd(_ref) {
let {
type = 'CollectionPage',
keyOverride,
hasPart
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$g);
const data = _extends({}, rest, {
hasPart: hasPart.map(setCreativeWork)
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "CollectionPage"
}));
}
function setManufacturer(manufacturer) {
if (manufacturer && (manufacturer.manufacturerName || manufacturer.manufacturerLogo)) {
return {
'@type': 'Organization',
name: manufacturer.manufacturerName,
logo: setImage(manufacturer.manufacturerLogo)
};
}
return undefined;
}
function setBrand(brand) {
if (brand) {
return {
'@type': 'Brand',
name: brand
};
}
return undefined;
}
const _excluded$f = ["type", "keyOverride", "images", "brand", "reviews", "aggregateRating", "manufacturerLogo", "manufacturerName", "offers", "aggregateOffer", "productName"];
function ProductJsonLd(_ref) {
let {
type = 'Product',
keyOverride,
images,
brand,
reviews,
aggregateRating,
manufacturerLogo,
manufacturerName,
offers,
aggregateOffer,
productName
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$f);
const data = _extends({}, rest, {
image: images,
brand: setBrand(brand),
review: setReviews(reviews),
aggregateRating: setAggregateRating(aggregateRating),
manufacturer: setManufacturer({
manufacturerLogo,
manufacturerName
}),
offers: offers ? setOffers(offers) : setAggregateOffer(aggregateOffer),
name: productName
});
return /*#__PURE__*/React.createElement(JsonLd, _extends({
type: type,
keyOverride: keyOverride
}, data, {
scriptKey: "Product"
}));
}
const _excluded$e = ["type", "keyOverride", "priceCurrency", "price", "aggregateRating", "review"];
function SoftwareAppJsonLd(_ref) {
let {
type = 'SoftwareApplication',
keyOverride,
priceCurrency,
price,
aggregateRating,
review
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, _excluded$e);
const data = _extends({}, rest, {
offers: {
'@type': 'Offer',
price,
priceCurrency: priceCurrency
},
aggregateRating: setAggregateRating(aggregateRating)