UNPKG

datocms-client

Version:

For new DatoCMS users, we recommend @datocms/cma-client-node

294 lines (236 loc) 10.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = seoTagsBuilder; exports.builders = void 0; var _humps = require("humps"); var _striptags = _interopRequireDefault(require("striptags")); var _datocmsStructuredTextToPlainText = require("datocms-structured-text-to-plain-text"); var _marked = require("marked"); var _localizedRead = _interopRequireDefault(require("./localizedRead")); var _buildFileUrl = _interopRequireDefault(require("./buildFileUrl")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var tag = function tag(tagName, attributes) { return { tagName: tagName, attributes: attributes }; }; var metaTag = function metaTag(name, content) { return tag('meta', { name: name, content: content }); }; var ogTag = function ogTag(property, content) { return tag('meta', { property: property, content: content }); }; var cardTag = function cardTag(name, content) { return tag('meta', { name: name, content: content }); }; var contentTag = function contentTag(tagName, content) { return { tagName: tagName, content: content }; }; function seoAttributeWithFallback(attribute, alternative, itemEntity, entitiesRepo, i18n) { var site = entitiesRepo.site; var itemSeoValue; var seoField = itemEntity && itemEntity.itemType.fields.find(function (f) { return f.fieldType === 'seo'; }); if (seoField) { var itemSeoFieldValue = (0, _localizedRead["default"])(itemEntity, (0, _humps.camelize)(seoField.apiKey), seoField.localized, i18n); itemSeoValue = itemSeoFieldValue && itemSeoFieldValue[attribute]; } var globalSeoValue = (0, _localizedRead["default"])(site, 'globalSeo', site.locales.length > 1, i18n); var fallbackSeoValue = globalSeoValue && globalSeoValue.fallbackSeo && globalSeoValue.fallbackSeo[attribute]; return itemSeoValue || alternative || fallbackSeoValue; } var builders = { title: function title(itemEntity, entitiesRepo, i18n) { var site = entitiesRepo.site; var findTitleField = function findTitleField() { var itemType = itemEntity && itemEntity.itemType; if (!itemType) { return undefined; } if (itemType.titleField && itemType.titleField.fieldType !== 'link') { return itemType.titleField; } var fields = itemType.fields.sort(function (a, b) { return a.apiKey.localeCompare(b.apiKey); }); var headingField = fields.find(function (field) { return field.fieldType === 'string' && field.appearance.editor === 'single_line' && field.appearance.parameters.heading; }); if (headingField) { return headingField; } return fields.find(function (field) { return field.fieldType === 'string'; }); }; var titleField = findTitleField(); var itemTitle = seoAttributeWithFallback('title', titleField && (0, _localizedRead["default"])(itemEntity, (0, _humps.camelize)(titleField.apiKey), titleField.localized, i18n), itemEntity, entitiesRepo, i18n); if (!itemTitle) { return undefined; } var globalSeoValue = (0, _localizedRead["default"])(site, 'globalSeo', site.locales.length > 1, i18n); var suffix = globalSeoValue && globalSeoValue.titleSuffix || ''; var titleWithSuffix = (itemTitle + suffix).length <= 60 ? itemTitle + suffix : itemTitle; return [contentTag('title', titleWithSuffix), ogTag('og:title', itemTitle), cardTag('twitter:title', itemTitle)]; }, description: function description(itemEntity, entitiesRepo, i18n) { var itemType = itemEntity && itemEntity.itemType; var excerptField = itemType && itemType.excerptField; var findExcerptValue = function findExcerptValue() { var value = (0, _localizedRead["default"])(itemEntity, (0, _humps.camelize)(excerptField.apiKey), excerptField.localized, i18n); var transformExcerptValue = function transformExcerptValue() { switch (excerptField.fieldType) { case 'text': if (excerptField.appearance.editor === 'wysiwyg') { return (0, _striptags["default"])(value); } if (excerptField.appearance.editor === 'markdown') { return (0, _striptags["default"])(_marked.marked.parse(value).replace('\n', '')); } return value; case 'structured_text': return (0, _datocmsStructuredTextToPlainText.render)(value); case 'string': return value; default: return undefined; } }; var postTransformationValue = value && transformExcerptValue(); return postTransformationValue && postTransformationValue.length > 200 ? "".concat(postTransformationValue.slice(0, 200), "...") : postTransformationValue; }; var excerptValue = excerptField && findExcerptValue(); var description = seoAttributeWithFallback('description', excerptValue, itemEntity, entitiesRepo, i18n); if (!description) { return undefined; } return [metaTag('description', description), ogTag('og:description', description), cardTag('twitter:description', description)]; }, robots: function robots(itemEntity, entitiesRepo) { if (!entitiesRepo.site.noIndex) return undefined; return metaTag('robots', 'noindex'); }, twitterSite: function twitterSite(itemEntity, entitiesRepo) { var site = entitiesRepo.site; if (site.globalSeo && site.globalSeo.twitterAccount) { return cardTag('twitter:site', site.globalSeo.twitterAccount); } return undefined; }, twitterCard: function twitterCard(itemEntity, entitiesRepo, i18n) { var card = seoAttributeWithFallback('twitterCard', null, itemEntity, entitiesRepo, i18n); return cardTag('twitter:card', card || 'summary'); }, articleModifiedTime: function articleModifiedTime(itemEntity) { if (!itemEntity) return undefined; var date = new Date(Date.parse(itemEntity.meta.updatedAt)); return ogTag('article:modified_time', "".concat(date.toISOString().split('.')[0], "Z")); }, articlePublishedTime: function articlePublishedTime(itemEntity) { if (!itemEntity) return undefined; if (!itemEntity.meta.firstPublishedAt) return undefined; var date = new Date(Date.parse(itemEntity.meta.firstPublishedAt)); return ogTag('article:published_time', "".concat(date.toISOString().split('.')[0], "Z")); }, articlePublisher: function articlePublisher(itemEntity, entitiesRepo) { var site = entitiesRepo.site; if (site.globalSeo && site.globalSeo.facebookPageUrl) { return ogTag('article:publisher', site.globalSeo.facebookPageUrl); } return undefined; }, ogLocale: function ogLocale(itemEntity, entitiesRepo, i18n) { if (i18n.locale.includes('-')) { return ogTag('og:locale', i18n.locale.replace(/-/, '_')); } return ogTag('og:locale', "".concat(i18n.locale, "_").concat(i18n.locale.toUpperCase())); }, ogType: function ogType(itemEntity) { if (!itemEntity || itemEntity.singleton) { return ogTag('og:type', 'website'); } return ogTag('og:type', 'article'); }, ogSiteName: function ogSiteName(itemEntity, entitiesRepo) { var site = entitiesRepo.site; if (site.globalSeo && site.globalSeo.siteName) { return ogTag('og:site_name', site.globalSeo.siteName); } return undefined; }, image: function image(itemEntity, entitiesRepo, i18n) { var site = entitiesRepo.site; var findImagePreviewField = function findImagePreviewField() { var itemType = itemEntity && itemEntity.itemType; if (!itemType) { return undefined; } if (itemType.imagePreviewField && itemType.imagePreviewField.fieldType !== 'link') { return itemType.imagePreviewField; } var fields = itemType.fields.sort(function (a, b) { return a.apiKey.localeCompare(b.apiKey); }); var fileFieldWithImageValidations = fields.find(function (field) { return ['file', 'gallery'].includes(field.fieldType) && field.validators && field.validators.extension && field.validators.extension.predefinedList === 'image'; }); return fileFieldWithImageValidations || fields.find(function (field) { return ['file', 'gallery'].includes(field.fieldType); }); }; var itemImageField = findImagePreviewField(); var fallbackRawValue = itemImageField && (0, _localizedRead["default"])(itemEntity, (0, _humps.camelize)(itemImageField.apiKey), itemImageField.localized, i18n); var fallbackImage = fallbackRawValue && Array.isArray(fallbackRawValue) ? fallbackRawValue[0] : fallbackRawValue; var fallbackImageId = fallbackImage && fallbackImage.uploadId; var finalUploadId = seoAttributeWithFallback('image', fallbackImageId, itemEntity, entitiesRepo, i18n); if (!finalUploadId) { return undefined; } var finalUpload = entitiesRepo.findEntity('upload', finalUploadId); if (!finalUpload.width) { return undefined; } var url = (0, _buildFileUrl["default"])(finalUpload, entitiesRepo, { w: '1000', fit: 'max', auto: 'format' }); var defaultFieldMetadata = finalUpload.defaultFieldMetadata; var altLocale = defaultFieldMetadata ? site.locales.find(function (locale) { return defaultFieldMetadata[locale] && defaultFieldMetadata[locale].alt; }) : site.locales[0]; var altValue = defaultFieldMetadata && defaultFieldMetadata[altLocale] && defaultFieldMetadata[altLocale].alt; return [ogTag('og:image', url), cardTag('twitter:image', url), ogTag('og:image:width', finalUpload.width), ogTag('og:image:height', finalUpload.height), altValue && ogTag('og:image:alt', altValue), altValue && ogTag('twitter:image:alt', altValue)].filter(function (x) { return !!x; }); } }; exports.builders = builders; function seoTagsBuilder(itemEntity, entitiesRepo, i18n) { return Object.values(builders).reduce(function (acc, builder) { var result = builder(itemEntity, entitiesRepo, i18n); if (result) { if (Array.isArray(result)) { return [].concat(acc, result); } return [].concat(acc, [result]); } return acc; }, []); }