@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 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
- const storyUrl = story.url || `${config["sketches-host"]}/${story.slug}`;
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
@@ -93,7 +93,8 @@ export class MetaTagList {
93
93
  * },
94
94
  * enableNewsArticle: true
95
95
  * },
96
- * ampStoryPages: true
96
+ * ampStoryPages: true,
97
+ * enableMetaDescriptionsFallback: true
97
98
  * });
98
99
  * ```
99
100
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quintype/seo",
3
- "version": "1.41.4",
3
+ "version": "1.41.5-description-fallback.0",
4
4
  "description": "SEO Modules for Quintype",
5
5
  "main": "dist/index.cjs.js",
6
6
  "repository": "https://github.com/quintype/quintype-node-seo",
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
- const storyUrl = story.url || `${config["sketches-host"]}/${story.slug}`;
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 buildTagsFromStory(config, get(data, ["story"]), url, data) || getSeoData(config, "home-page", data, url);
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
+ }