@quintype/seo 1.41.4 → 1.41.5-description-fallback.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +33 -8
- package/index.js +2 -1
- package/package.json +1 -1
- package/src/text-tags.js +25 -8
- package/src/utils.js +17 -0
package/dist/index.cjs.js
CHANGED
|
@@ -49,6 +49,20 @@ function isStoryPublic(story) {
|
|
|
49
49
|
return story.access === undefined || story.access === null || story.access === 'public';
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
function getTextOfCards(story) {
|
|
53
|
+
if (story && story.cards) {
|
|
54
|
+
story.cards.map(item => {
|
|
55
|
+
return item['story-elements'].reduce((acc, currentItem) => {
|
|
56
|
+
const elementType = currentItem.subtype || currentItem.type || '';
|
|
57
|
+
if (elementType === 'text') {
|
|
58
|
+
acc.push(currentItem.text);
|
|
59
|
+
}
|
|
60
|
+
return acc;
|
|
61
|
+
}, []);
|
|
62
|
+
}).join(' ').replace(/(<([^>]+)>)/gi, '');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
52
66
|
function showAmpTag({ ampStoryPages = true }, pageType, story) {
|
|
53
67
|
if (!ampStoryPages || pageType !== "story-page") {
|
|
54
68
|
return false;
|
|
@@ -931,7 +945,7 @@ function StructuredDataTags({ structuredData = {} }, config, pageType, response
|
|
|
931
945
|
return tags;
|
|
932
946
|
}
|
|
933
947
|
|
|
934
|
-
function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
948
|
+
function buildTagsFromStory(config, story, url = {}, data = {}, seoConfig = {}) {
|
|
935
949
|
if (!story) return;
|
|
936
950
|
|
|
937
951
|
function getStoryCardMetadata(cardId) {
|
|
@@ -952,18 +966,27 @@ function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
|
952
966
|
|
|
953
967
|
const seo = story.seo || {};
|
|
954
968
|
|
|
955
|
-
|
|
969
|
+
let descriptionWithExtraFallback = "";
|
|
970
|
+
let ogDescriptionWithExtraFallback = "";
|
|
971
|
+
if (seoConfig.enableMetaDescriptionFallback) {
|
|
972
|
+
const fetch160Characters = data => data ? data.substring(0, 160) : null;
|
|
973
|
+
const fullStoryTextElementContent = getTextOfCards(story);
|
|
974
|
+
descriptionWithExtraFallback = fetch160Characters(story.subheadline) || fetch160Characters(fullStoryTextElementContent);
|
|
975
|
+
ogDescriptionWithExtraFallback = fetch160Characters(fullStoryTextElementContent) || fetch160Characters(story.subheadline) || seo["meta-description"];
|
|
976
|
+
}
|
|
956
977
|
|
|
978
|
+
const storyUrl = story.url || `${config["sketches-host"]}/${story.slug}`;
|
|
957
979
|
const customSeo = lodash.get(data, ["data", "customSeo"], {});
|
|
958
980
|
const authors = lodash.get(story, ["authors"], []).map(author => author.name);
|
|
959
981
|
const title = customSeo.title || seo["meta-title"] || story.headline;
|
|
960
982
|
const pageTitle = customSeo["page-title"] || seo["meta-title"] || story.headline;
|
|
961
|
-
const description = customSeo.description || seo["meta-description"] || story.summary;
|
|
983
|
+
const description = customSeo.description || seo["meta-description"] || story.summary || descriptionWithExtraFallback;
|
|
962
984
|
const keywords = (customSeo.keywords || seo["meta-keywords"] || (story.tags || []).map(tag => tag.name)).join(",");
|
|
963
985
|
const ogUrl = customSeo.ogUrl || lodash.get(seo, ["og", "url"]) || storyUrl;
|
|
964
986
|
const getOgTitle = customSeo.ogTitle || lodash.get(story, ["alternative", "social", "default", "headline"], story.headline) || story.headline;
|
|
965
|
-
const ogDescription = customSeo.ogDescription || story.summary;
|
|
987
|
+
const ogDescription = customSeo.ogDescription || story.summary || ogDescriptionWithExtraFallback;
|
|
966
988
|
const canonicalUrl = customSeo.canonicalUrl || story["canonical-url"] || storyUrl;
|
|
989
|
+
|
|
967
990
|
const storyMetaData = {
|
|
968
991
|
title,
|
|
969
992
|
"page-title": pageTitle,
|
|
@@ -1147,11 +1170,11 @@ function getSeoData(config, pageType, data, url = {}, seoConfig = {}) {
|
|
|
1147
1170
|
case "tag-page":
|
|
1148
1171
|
return buildTagsFromTopic(config, lodash.get(data, ["data", "tag"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
1149
1172
|
case "story-page":
|
|
1150
|
-
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
1173
|
+
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data, seoConfig) || getSeoData(config, "home-page", data, url);
|
|
1151
1174
|
case "visual-story":
|
|
1152
|
-
return buildTagsFromStory(config, lodash.get(data, ["story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
1175
|
+
return buildTagsFromStory(config, lodash.get(data, ["story"]), url, data, seoConfig) || getSeoData(config, "home-page", data, url);
|
|
1153
1176
|
case "story-page-amp":
|
|
1154
|
-
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
1177
|
+
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data, seoConfig) || getSeoData(config, "home-page", data, url);
|
|
1155
1178
|
case "author-page":
|
|
1156
1179
|
return buildTagsFromAuthor(config, lodash.get(data, ["data", "author"], {}), url, data) || getSeoData(config, "home-page", data, url);
|
|
1157
1180
|
case "static-page":
|
|
@@ -1204,6 +1227,7 @@ const SKIP_CANONICAL = "__SKIP__CANONICAL__";
|
|
|
1204
1227
|
* @param {boolean} seoConfig.enableOgTags Add og tags for Facebook
|
|
1205
1228
|
* @param {boolean} seoConfig.enableTwitterCards Add twitter tags
|
|
1206
1229
|
* @param {boolean} seoConfig.enableNews Add tags for Google News, like news_keywords
|
|
1230
|
+
* @param {boolean} seoConfig.enableMetaDescriptionsFallback Add extra fallbacks for meta description, og:description and twitter:description
|
|
1207
1231
|
* @param {Object} seoConfig.customTags Add tags for a custom page type. Usually looks like `{"custom-page": {"title": "value", "canonicalUrl": "value"}}`
|
|
1208
1232
|
* @param {...*} params See {@link Generator} for other Parameters
|
|
1209
1233
|
*/
|
|
@@ -1338,7 +1362,8 @@ class MetaTagList {
|
|
|
1338
1362
|
* },
|
|
1339
1363
|
* enableNewsArticle: true
|
|
1340
1364
|
* },
|
|
1341
|
-
* ampStoryPages: true
|
|
1365
|
+
* ampStoryPages: true,
|
|
1366
|
+
* enableMetaDescriptionsFallback: true
|
|
1342
1367
|
* });
|
|
1343
1368
|
* ```
|
|
1344
1369
|
*/
|
package/index.js
CHANGED
package/package.json
CHANGED
package/src/text-tags.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { get, isEmpty } from "lodash";
|
|
2
|
-
import { objectToTags } from "./utils";
|
|
2
|
+
import { getTextOfCards, objectToTags } from "./utils";
|
|
3
3
|
|
|
4
|
-
function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
4
|
+
function buildTagsFromStory(config, story, url = {}, data = {}, seoConfig = {}) {
|
|
5
5
|
if (!story) return;
|
|
6
6
|
|
|
7
7
|
function getStoryCardMetadata(cardId) {
|
|
@@ -22,19 +22,32 @@ function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
|
22
22
|
|
|
23
23
|
const seo = story.seo || {};
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
let descriptionWithExtraFallback = "";
|
|
26
|
+
let ogDescriptionWithExtraFallback = "";
|
|
27
|
+
if (seoConfig.enableMetaDescriptionFallback) {
|
|
28
|
+
const fetch160Characters = (data) => (data ? data.substring(0, 160) : null);
|
|
29
|
+
const fullStoryTextElementContent = getTextOfCards(story);
|
|
30
|
+
descriptionWithExtraFallback =
|
|
31
|
+
fetch160Characters(story.subheadline) || fetch160Characters(fullStoryTextElementContent);
|
|
32
|
+
ogDescriptionWithExtraFallback =
|
|
33
|
+
fetch160Characters(fullStoryTextElementContent) ||
|
|
34
|
+
fetch160Characters(story.subheadline) ||
|
|
35
|
+
seo["meta-description"];
|
|
36
|
+
}
|
|
26
37
|
|
|
38
|
+
const storyUrl = story.url || `${config["sketches-host"]}/${story.slug}`;
|
|
27
39
|
const customSeo = get(data, ["data", "customSeo"], {});
|
|
28
40
|
const authors = get(story, ["authors"], []).map((author) => author.name);
|
|
29
41
|
const title = customSeo.title || seo["meta-title"] || story.headline;
|
|
30
42
|
const pageTitle = customSeo["page-title"] || seo["meta-title"] || story.headline;
|
|
31
|
-
const description = customSeo.description || seo["meta-description"] || story.summary;
|
|
43
|
+
const description = customSeo.description || seo["meta-description"] || story.summary || descriptionWithExtraFallback;
|
|
32
44
|
const keywords = (customSeo.keywords || seo["meta-keywords"] || (story.tags || []).map((tag) => tag.name)).join(",");
|
|
33
45
|
const ogUrl = customSeo.ogUrl || get(seo, ["og", "url"]) || storyUrl;
|
|
34
46
|
const getOgTitle =
|
|
35
47
|
customSeo.ogTitle || get(story, ["alternative", "social", "default", "headline"], story.headline) || story.headline;
|
|
36
|
-
const ogDescription = customSeo.ogDescription || story.summary;
|
|
48
|
+
const ogDescription = customSeo.ogDescription || story.summary || ogDescriptionWithExtraFallback;
|
|
37
49
|
const canonicalUrl = customSeo.canonicalUrl || story["canonical-url"] || storyUrl;
|
|
50
|
+
|
|
38
51
|
const storyMetaData = {
|
|
39
52
|
title,
|
|
40
53
|
"page-title": pageTitle,
|
|
@@ -230,14 +243,17 @@ function getSeoData(config, pageType, data, url = {}, seoConfig = {}) {
|
|
|
230
243
|
);
|
|
231
244
|
case "story-page":
|
|
232
245
|
return (
|
|
233
|
-
buildTagsFromStory(config, get(data, ["data", "story"]), url, data) ||
|
|
246
|
+
buildTagsFromStory(config, get(data, ["data", "story"]), url, data, seoConfig) ||
|
|
234
247
|
getSeoData(config, "home-page", data, url)
|
|
235
248
|
);
|
|
236
249
|
case "visual-story":
|
|
237
|
-
return
|
|
250
|
+
return (
|
|
251
|
+
buildTagsFromStory(config, get(data, ["story"]), url, data, seoConfig) ||
|
|
252
|
+
getSeoData(config, "home-page", data, url)
|
|
253
|
+
);
|
|
238
254
|
case "story-page-amp":
|
|
239
255
|
return (
|
|
240
|
-
buildTagsFromStory(config, get(data, ["data", "story"]), url, data) ||
|
|
256
|
+
buildTagsFromStory(config, get(data, ["data", "story"]), url, data, seoConfig) ||
|
|
241
257
|
getSeoData(config, "home-page", data, url)
|
|
242
258
|
);
|
|
243
259
|
case "author-page":
|
|
@@ -298,6 +314,7 @@ const SKIP_CANONICAL = "__SKIP__CANONICAL__";
|
|
|
298
314
|
* @param {boolean} seoConfig.enableOgTags Add og tags for Facebook
|
|
299
315
|
* @param {boolean} seoConfig.enableTwitterCards Add twitter tags
|
|
300
316
|
* @param {boolean} seoConfig.enableNews Add tags for Google News, like news_keywords
|
|
317
|
+
* @param {boolean} seoConfig.enableMetaDescriptionsFallback Add extra fallbacks for meta description, og:description and twitter:description
|
|
301
318
|
* @param {Object} seoConfig.customTags Add tags for a custom page type. Usually looks like `{"custom-page": {"title": "value", "canonicalUrl": "value"}}`
|
|
302
319
|
* @param {...*} params See {@link Generator} for other Parameters
|
|
303
320
|
*/
|
package/src/utils.js
CHANGED
|
@@ -33,3 +33,20 @@ export function getQueryParams(url) {
|
|
|
33
33
|
export function isStoryPublic(story) {
|
|
34
34
|
return story.access === undefined || story.access === null || story.access === 'public';
|
|
35
35
|
}
|
|
36
|
+
|
|
37
|
+
export function getTextOfCards(story) {
|
|
38
|
+
if (story && story.cards) {
|
|
39
|
+
story.cards
|
|
40
|
+
.map((item) => {
|
|
41
|
+
return item['story-elements'].reduce((acc, currentItem) => {
|
|
42
|
+
const elementType = currentItem.subtype || currentItem.type || '';
|
|
43
|
+
if (elementType === 'text') {
|
|
44
|
+
acc.push(currentItem.text);
|
|
45
|
+
}
|
|
46
|
+
return acc;
|
|
47
|
+
}, []);
|
|
48
|
+
})
|
|
49
|
+
.join(' ')
|
|
50
|
+
.replace(/(<([^>]+)>)/gi, '');
|
|
51
|
+
}
|
|
52
|
+
}
|