datocms-client
Version:
For new DatoCMS users, we recommend @datocms/cma-client-node
294 lines (236 loc) • 10.3 kB
JavaScript
"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;
}, []);
}