@quintype/seo 1.41.5-description-fallback.2 → 1.42.0-peer-deps-removal.2
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 +9 -37
- package/index.js +1 -2
- package/package.json +2 -4
- package/src/text-tags.js +8 -27
- package/src/utils.js +2 -19
- package/test/text_tags_test.js +384 -773
package/dist/index.cjs.js
CHANGED
|
@@ -6,8 +6,8 @@ var lodash = require('lodash');
|
|
|
6
6
|
var React = require('react');
|
|
7
7
|
var ReactDomServer = require('react-dom/server');
|
|
8
8
|
var get = require('lodash/get');
|
|
9
|
-
var dateFnsTz = require('date-fns-tz');
|
|
10
9
|
var url = require('url');
|
|
10
|
+
var dateFnsTz = require('date-fns-tz');
|
|
11
11
|
var isUndefined = require('lodash/isUndefined');
|
|
12
12
|
var omitBy = require('lodash/omitBy');
|
|
13
13
|
var quintypeJs = require('quintype-js');
|
|
@@ -49,20 +49,6 @@ 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
|
-
return 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
|
-
|
|
66
52
|
function showAmpTag({ ampStoryPages = true }, pageType, story) {
|
|
67
53
|
if (!ampStoryPages || pageType !== "story-page") {
|
|
68
54
|
return false;
|
|
@@ -945,7 +931,7 @@ function StructuredDataTags({ structuredData = {} }, config, pageType, response
|
|
|
945
931
|
return tags;
|
|
946
932
|
}
|
|
947
933
|
|
|
948
|
-
function buildTagsFromStory(config, story, url = {}, data = {}
|
|
934
|
+
function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
949
935
|
if (!story) return;
|
|
950
936
|
|
|
951
937
|
function getStoryCardMetadata(cardId) {
|
|
@@ -966,29 +952,18 @@ function buildTagsFromStory(config, story, url = {}, data = {}, seoConfig = {})
|
|
|
966
952
|
|
|
967
953
|
const seo = story.seo || {};
|
|
968
954
|
|
|
969
|
-
let descriptionWithExtraFallback = "";
|
|
970
|
-
let ogDescriptionWithExtraFallback = "";
|
|
971
|
-
const enableMetaDescriptionFallback = lodash.get(seoConfig, ["enableMetaDescriptionFallback"], false);
|
|
972
|
-
if (enableMetaDescriptionFallback) {
|
|
973
|
-
const subHeadline = lodash.get(story, ["subheadline"]);
|
|
974
|
-
const fetch160Characters = data => data ? data.substring(0, 160) : null;
|
|
975
|
-
const fullStoryTextElementContent = getTextOfCards(story);
|
|
976
|
-
descriptionWithExtraFallback = fetch160Characters(subHeadline) || fetch160Characters(fullStoryTextElementContent);
|
|
977
|
-
ogDescriptionWithExtraFallback = fetch160Characters(fullStoryTextElementContent) || fetch160Characters(subHeadline) || lodash.get(seo, ["meta-description"]);
|
|
978
|
-
}
|
|
979
|
-
|
|
980
955
|
const storyUrl = story.url || `${config["sketches-host"]}/${story.slug}`;
|
|
956
|
+
|
|
981
957
|
const customSeo = lodash.get(data, ["data", "customSeo"], {});
|
|
982
958
|
const authors = lodash.get(story, ["authors"], []).map(author => author.name);
|
|
983
959
|
const title = customSeo.title || seo["meta-title"] || story.headline;
|
|
984
960
|
const pageTitle = customSeo["page-title"] || seo["meta-title"] || story.headline;
|
|
985
|
-
const description = customSeo.description || seo["meta-description"] || story.summary
|
|
961
|
+
const description = customSeo.description || seo["meta-description"] || story.summary;
|
|
986
962
|
const keywords = (customSeo.keywords || seo["meta-keywords"] || (story.tags || []).map(tag => tag.name)).join(",");
|
|
987
963
|
const ogUrl = customSeo.ogUrl || lodash.get(seo, ["og", "url"]) || storyUrl;
|
|
988
964
|
const getOgTitle = customSeo.ogTitle || lodash.get(story, ["alternative", "social", "default", "headline"], story.headline) || story.headline;
|
|
989
|
-
const ogDescription = customSeo.ogDescription || story.summary
|
|
965
|
+
const ogDescription = customSeo.ogDescription || story.summary;
|
|
990
966
|
const canonicalUrl = customSeo.canonicalUrl || story["canonical-url"] || storyUrl;
|
|
991
|
-
|
|
992
967
|
const storyMetaData = {
|
|
993
968
|
title,
|
|
994
969
|
"page-title": pageTitle,
|
|
@@ -1098,7 +1073,6 @@ function buildCustomTags(customTags = {}, pageType = "") {
|
|
|
1098
1073
|
function buildTagsFromStaticPage(config, page, url = {}, data) {
|
|
1099
1074
|
const seoData = lodash.get(page, ["metadata", "seo"], {});
|
|
1100
1075
|
const customSeo = lodash.get(data, ["data", "customSeo"], {});
|
|
1101
|
-
if (lodash.isEmpty(seoData) && lodash.isEmpty(customSeo)) return;
|
|
1102
1076
|
|
|
1103
1077
|
const { "meta-title": metaTitle, "meta-description": metaDescription, "meta-keywords": keywords } = seoData;
|
|
1104
1078
|
|
|
@@ -1172,11 +1146,11 @@ function getSeoData(config, pageType, data, url = {}, seoConfig = {}) {
|
|
|
1172
1146
|
case "tag-page":
|
|
1173
1147
|
return buildTagsFromTopic(config, lodash.get(data, ["data", "tag"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
1174
1148
|
case "story-page":
|
|
1175
|
-
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data
|
|
1149
|
+
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
1176
1150
|
case "visual-story":
|
|
1177
|
-
return buildTagsFromStory(config, lodash.get(data, ["story"]), url, data
|
|
1151
|
+
return buildTagsFromStory(config, lodash.get(data, ["story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
1178
1152
|
case "story-page-amp":
|
|
1179
|
-
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data
|
|
1153
|
+
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
1180
1154
|
case "author-page":
|
|
1181
1155
|
return buildTagsFromAuthor(config, lodash.get(data, ["data", "author"], {}), url, data) || getSeoData(config, "home-page", data, url);
|
|
1182
1156
|
case "static-page":
|
|
@@ -1229,7 +1203,6 @@ const SKIP_CANONICAL = "__SKIP__CANONICAL__";
|
|
|
1229
1203
|
* @param {boolean} seoConfig.enableOgTags Add og tags for Facebook
|
|
1230
1204
|
* @param {boolean} seoConfig.enableTwitterCards Add twitter tags
|
|
1231
1205
|
* @param {boolean} seoConfig.enableNews Add tags for Google News, like news_keywords
|
|
1232
|
-
* @param {boolean} seoConfig.enableMetaDescriptionFallback Add extra fallbacks for meta description, og:description and twitter:description
|
|
1233
1206
|
* @param {Object} seoConfig.customTags Add tags for a custom page type. Usually looks like `{"custom-page": {"title": "value", "canonicalUrl": "value"}}`
|
|
1234
1207
|
* @param {...*} params See {@link Generator} for other Parameters
|
|
1235
1208
|
*/
|
|
@@ -1364,8 +1337,7 @@ class MetaTagList {
|
|
|
1364
1337
|
* },
|
|
1365
1338
|
* enableNewsArticle: true
|
|
1366
1339
|
* },
|
|
1367
|
-
* ampStoryPages: true
|
|
1368
|
-
* enableMetaDescriptionFallback: true
|
|
1340
|
+
* ampStoryPages: true
|
|
1369
1341
|
* });
|
|
1370
1342
|
* ```
|
|
1371
1343
|
*/
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quintype/seo",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.42.0-peer-deps-removal.2",
|
|
4
4
|
"description": "SEO Modules for Quintype",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"repository": "https://github.com/quintype/quintype-node-seo",
|
|
7
7
|
"author": "Quintype Developers <dev-core@quintype.com>",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"lodash": "^4.0.0"
|
|
11
|
-
"react": "^16.0.0",
|
|
12
|
-
"react-dom": "^16.0.0"
|
|
10
|
+
"lodash": "^4.0.0"
|
|
13
11
|
},
|
|
14
12
|
"scripts": {
|
|
15
13
|
"build": "rollup -c",
|
package/src/text-tags.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { get, isEmpty } from "lodash";
|
|
2
|
-
import {
|
|
2
|
+
import { objectToTags } from "./utils";
|
|
3
3
|
|
|
4
|
-
function buildTagsFromStory(config, story, url = {}, data = {}
|
|
4
|
+
function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
5
5
|
if (!story) return;
|
|
6
6
|
|
|
7
7
|
function getStoryCardMetadata(cardId) {
|
|
@@ -22,33 +22,19 @@ function buildTagsFromStory(config, story, url = {}, data = {}, seoConfig = {})
|
|
|
22
22
|
|
|
23
23
|
const seo = story.seo || {};
|
|
24
24
|
|
|
25
|
-
let descriptionWithExtraFallback = "";
|
|
26
|
-
let ogDescriptionWithExtraFallback = "";
|
|
27
|
-
const enableMetaDescriptionFallback = get(seoConfig, ["enableMetaDescriptionFallback"], false);
|
|
28
|
-
if (enableMetaDescriptionFallback) {
|
|
29
|
-
const subHeadline = get(story, ["subheadline"]);
|
|
30
|
-
const fetch160Characters = (data) => (data ? data.substring(0, 160) : null);
|
|
31
|
-
const fullStoryTextElementContent = getTextOfCards(story);
|
|
32
|
-
descriptionWithExtraFallback = fetch160Characters(subHeadline) || fetch160Characters(fullStoryTextElementContent);
|
|
33
|
-
ogDescriptionWithExtraFallback =
|
|
34
|
-
fetch160Characters(fullStoryTextElementContent) ||
|
|
35
|
-
fetch160Characters(subHeadline) ||
|
|
36
|
-
get(seo, ["meta-description"]);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
25
|
const storyUrl = story.url || `${config["sketches-host"]}/${story.slug}`;
|
|
26
|
+
|
|
40
27
|
const customSeo = get(data, ["data", "customSeo"], {});
|
|
41
28
|
const authors = get(story, ["authors"], []).map((author) => author.name);
|
|
42
29
|
const title = customSeo.title || seo["meta-title"] || story.headline;
|
|
43
30
|
const pageTitle = customSeo["page-title"] || seo["meta-title"] || story.headline;
|
|
44
|
-
const description = customSeo.description || seo["meta-description"] || story.summary
|
|
31
|
+
const description = customSeo.description || seo["meta-description"] || story.summary;
|
|
45
32
|
const keywords = (customSeo.keywords || seo["meta-keywords"] || (story.tags || []).map((tag) => tag.name)).join(",");
|
|
46
33
|
const ogUrl = customSeo.ogUrl || get(seo, ["og", "url"]) || storyUrl;
|
|
47
34
|
const getOgTitle =
|
|
48
35
|
customSeo.ogTitle || get(story, ["alternative", "social", "default", "headline"], story.headline) || story.headline;
|
|
49
|
-
const ogDescription = customSeo.ogDescription || story.summary
|
|
36
|
+
const ogDescription = customSeo.ogDescription || story.summary;
|
|
50
37
|
const canonicalUrl = customSeo.canonicalUrl || story["canonical-url"] || storyUrl;
|
|
51
|
-
|
|
52
38
|
const storyMetaData = {
|
|
53
39
|
title,
|
|
54
40
|
"page-title": pageTitle,
|
|
@@ -158,7 +144,6 @@ function buildCustomTags(customTags = {}, pageType = "") {
|
|
|
158
144
|
function buildTagsFromStaticPage(config, page, url = {}, data) {
|
|
159
145
|
const seoData = get(page, ["metadata", "seo"], {});
|
|
160
146
|
const customSeo = get(data, ["data", "customSeo"], {});
|
|
161
|
-
if (isEmpty(seoData) && isEmpty(customSeo)) return;
|
|
162
147
|
|
|
163
148
|
const { "meta-title": metaTitle, "meta-description": metaDescription, "meta-keywords": keywords } = seoData;
|
|
164
149
|
|
|
@@ -244,17 +229,14 @@ function getSeoData(config, pageType, data, url = {}, seoConfig = {}) {
|
|
|
244
229
|
);
|
|
245
230
|
case "story-page":
|
|
246
231
|
return (
|
|
247
|
-
buildTagsFromStory(config, get(data, ["data", "story"]), url, data
|
|
232
|
+
buildTagsFromStory(config, get(data, ["data", "story"]), url, data) ||
|
|
248
233
|
getSeoData(config, "home-page", data, url)
|
|
249
234
|
);
|
|
250
235
|
case "visual-story":
|
|
251
|
-
return (
|
|
252
|
-
buildTagsFromStory(config, get(data, ["story"]), url, data, seoConfig) ||
|
|
253
|
-
getSeoData(config, "home-page", data, url)
|
|
254
|
-
);
|
|
236
|
+
return buildTagsFromStory(config, get(data, ["story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
255
237
|
case "story-page-amp":
|
|
256
238
|
return (
|
|
257
|
-
buildTagsFromStory(config, get(data, ["data", "story"]), url, data
|
|
239
|
+
buildTagsFromStory(config, get(data, ["data", "story"]), url, data) ||
|
|
258
240
|
getSeoData(config, "home-page", data, url)
|
|
259
241
|
);
|
|
260
242
|
case "author-page":
|
|
@@ -315,7 +297,6 @@ const SKIP_CANONICAL = "__SKIP__CANONICAL__";
|
|
|
315
297
|
* @param {boolean} seoConfig.enableOgTags Add og tags for Facebook
|
|
316
298
|
* @param {boolean} seoConfig.enableTwitterCards Add twitter tags
|
|
317
299
|
* @param {boolean} seoConfig.enableNews Add tags for Google News, like news_keywords
|
|
318
|
-
* @param {boolean} seoConfig.enableMetaDescriptionFallback Add extra fallbacks for meta description, og:description and twitter:description
|
|
319
300
|
* @param {Object} seoConfig.customTags Add tags for a custom page type. Usually looks like `{"custom-page": {"title": "value", "canonicalUrl": "value"}}`
|
|
320
301
|
* @param {...*} params See {@link Generator} for other Parameters
|
|
321
302
|
*/
|
package/src/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { entries } from 'lodash';
|
|
1
|
+
import {entries} from 'lodash';
|
|
3
2
|
import { URL, URLSearchParams } from 'url';
|
|
3
|
+
import { format, utcToZonedTime } from 'date-fns-tz';
|
|
4
4
|
|
|
5
5
|
export function objectToTags(object) {
|
|
6
6
|
return entries(object)
|
|
@@ -33,20 +33,3 @@ 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
|
-
return 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
|
-
}
|