@quintype/seo 1.40.0-author-schema.1 → 1.40.1
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/CHANGELOG.md +16 -0
- package/dist/index.cjs.js +55 -53
- package/package.json +1 -1
- package/src/text-tags.js +116 -87
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [1.40.1](https://github.com/quintype/quintype-node-seo/compare/v1.40.0...v1.40.1) (2022-01-06)
|
|
6
|
+
|
|
7
|
+
## [1.40.0](https://github.com/quintype/quintype-node-seo/compare/v1.38.37-fix-canonical-url.0...v1.40.0) (2021-12-16)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* generate subscription based schema for news article ([#515](https://github.com/quintype/quintype-node-seo/issues/515)) ([39b2bad](https://github.com/quintype/quintype-node-seo/commit/39b2badaaa156ed6f01e8552e0d1f120b15361c0))
|
|
13
|
+
* **ImageTags:** Added support for og:image:alt and twitter:image:alt ([#501](https://github.com/quintype/quintype-node-seo/issues/501)) ([3d271ab](https://github.com/quintype/quintype-node-seo/commit/3d271ab21e009e0520ce1e6949bb1c8d32eeefa1))
|
|
14
|
+
* **Structure data tool testing:** Add support for testing structure data with all necessary schemas ⚡ ([#507](https://github.com/quintype/quintype-node-seo/issues/507)) ([aeea32a](https://github.com/quintype/quintype-node-seo/commit/aeea32a994bf4cf64cdf538d2ec3d785203b3817))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* **pickImage:** image is undefined of pickImage ([#508](https://github.com/quintype/quintype-node-seo/issues/508)) ([fecc8be](https://github.com/quintype/quintype-node-seo/commit/fecc8be44c86220456a511a89d197b52d60875c6))
|
|
20
|
+
|
|
5
21
|
## [1.39.0](https://github.com/quintype/quintype-node-seo/compare/v1.38.36...v1.39.0) (2021-08-23)
|
|
6
22
|
|
|
7
23
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -54,15 +54,15 @@ function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
|
54
54
|
|
|
55
55
|
function getStoryCardMetadata(cardId) {
|
|
56
56
|
const { metadata = {} } = story.cards.find(card => card.id === cardId) || {};
|
|
57
|
-
const urlWithCardId = `${config[
|
|
57
|
+
const urlWithCardId = `${config["sketches-host"]}/${story.slug}?cardId=${cardId}`;
|
|
58
58
|
|
|
59
|
-
if (metadata && !lodash.isEmpty(metadata) && metadata[
|
|
59
|
+
if (metadata && !lodash.isEmpty(metadata) && metadata["social-share"]) {
|
|
60
60
|
return {
|
|
61
|
-
title: metadata[
|
|
62
|
-
description: metadata[
|
|
61
|
+
title: metadata["social-share"].title || story.headline,
|
|
62
|
+
description: metadata["social-share"].message || story.summary,
|
|
63
63
|
ogUrl: urlWithCardId,
|
|
64
|
-
ogTitle: metadata[
|
|
65
|
-
ogDescription: metadata[
|
|
64
|
+
ogTitle: metadata["social-share"].title || story.headline,
|
|
65
|
+
ogDescription: metadata["social-share"].message || story.summary
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
return metadata;
|
|
@@ -70,10 +70,10 @@ function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
|
70
70
|
|
|
71
71
|
const seo = story.seo || {};
|
|
72
72
|
|
|
73
|
-
const storyUrl = story.url || `${config[
|
|
73
|
+
const storyUrl = story.url || `${config["sketches-host"]}/${story.slug}`;
|
|
74
74
|
|
|
75
75
|
const customSeo = lodash.get(data, ["data", "customSeo"], {});
|
|
76
|
-
const authors = lodash.get(story, [
|
|
76
|
+
const authors = lodash.get(story, ["authors"], []).map(author => author.name);
|
|
77
77
|
const title = customSeo.title || seo["meta-title"] || story.headline;
|
|
78
78
|
const pageTitle = customSeo["page-title"] || seo["meta-title"] || story.headline;
|
|
79
79
|
const description = customSeo.description || seo["meta-description"] || story.summary;
|
|
@@ -105,13 +105,13 @@ function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
|
105
105
|
function buildTagsFromTopic(config, tag, url = {}, data) {
|
|
106
106
|
if (lodash.isEmpty(tag)) return;
|
|
107
107
|
const customSeo = lodash.get(data, ["data", "customSeo"], {});
|
|
108
|
-
const tagName = customSeo.title || tag.name;
|
|
108
|
+
const tagName = customSeo.title || tag["meta-title"] || tag.name;
|
|
109
109
|
const pageTitle = customSeo["page-title"] || tagName;
|
|
110
|
-
const tagDescription = customSeo.description || tag[
|
|
111
|
-
const description = `Read stories listed under on ${
|
|
112
|
-
const tagUrl = `${config[
|
|
110
|
+
const tagDescription = customSeo.description || tag["meta-description"];
|
|
111
|
+
const description = `Read stories listed under on ${tag.name}`;
|
|
112
|
+
const tagUrl = `${config["sketches-host"]}${url.pathname}`;
|
|
113
113
|
const canonicalSlug = tag["canonical-slug"] || url.pathname;
|
|
114
|
-
const canonicalUrl = `${config[
|
|
114
|
+
const canonicalUrl = `${config["sketches-host"]}${canonicalSlug}`;
|
|
115
115
|
const ogTitle = customSeo.ogTitle || tagName;
|
|
116
116
|
const ogDescription = customSeo.ogDescription || description;
|
|
117
117
|
const topicMetaData = {
|
|
@@ -136,14 +136,14 @@ function buildTagsFromAuthor(config, author, url = {}, data) {
|
|
|
136
136
|
const pageTitle = customSeo["page-title"] || title;
|
|
137
137
|
const description = customSeo.description || author.bio || `View all articles written by ${title}`;
|
|
138
138
|
const ogTitle = customSeo.ogTitle || author.name;
|
|
139
|
-
const authorUrl = `${config[
|
|
139
|
+
const authorUrl = `${config["sketches-host"]}${url.pathname}`;
|
|
140
140
|
const ogDescription = customSeo.ogDescription || description;
|
|
141
141
|
|
|
142
142
|
return {
|
|
143
143
|
title,
|
|
144
144
|
"page-title": pageTitle,
|
|
145
145
|
description,
|
|
146
|
-
keywords: `${title},${config[
|
|
146
|
+
keywords: `${title},${config["publisher-name"]}`,
|
|
147
147
|
canonicalUrl: authorUrl,
|
|
148
148
|
ogUrl: authorUrl,
|
|
149
149
|
ogTitle,
|
|
@@ -151,7 +151,7 @@ function buildTagsFromAuthor(config, author, url = {}, data) {
|
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
function buildCustomTags(customTags = {}, pageType =
|
|
154
|
+
function buildCustomTags(customTags = {}, pageType = "") {
|
|
155
155
|
const configObject = customTags[pageType];
|
|
156
156
|
if (configObject) {
|
|
157
157
|
return configObject;
|
|
@@ -165,19 +165,21 @@ function buildCustomTags(customTags = {}, pageType = '') {
|
|
|
165
165
|
|
|
166
166
|
function getSeoData(config, pageType, data, url = {}, seoConfig = {}) {
|
|
167
167
|
function findRelevantConfig(ownerType, ownerId = null) {
|
|
168
|
-
const seoMetadata = config[
|
|
168
|
+
const seoMetadata = config["seo-metadata"].find(page => page["owner-type"] === ownerType && page["owner-id"] === ownerId) || {};
|
|
169
169
|
const { sections = [] } = config;
|
|
170
|
-
const section = sections.find(section => ownerType ==
|
|
170
|
+
const section = sections.find(section => ownerType == "section" && section.id === ownerId) || {};
|
|
171
171
|
const customSeo = lodash.get(data, ["data", "customSeo"], {});
|
|
172
172
|
if (seoMetadata.data || section.id || !lodash.isEmpty(customSeo)) {
|
|
173
173
|
const result = Object.assign({}, {
|
|
174
|
-
|
|
174
|
+
"page-title": customSeo["page-title"] || section.name,
|
|
175
175
|
title: customSeo.title || section.name,
|
|
176
|
-
canonicalUrl: customSeo["canonicalUrl"] || section[
|
|
176
|
+
canonicalUrl: customSeo["canonicalUrl"] || section["section-url"] || undefined
|
|
177
177
|
}, seoMetadata.data);
|
|
178
178
|
|
|
179
179
|
if (!result.description) {
|
|
180
|
-
const homeSeoData = config[
|
|
180
|
+
const homeSeoData = config["seo-metadata"].find(page => page["owner-type"] === "home") || {
|
|
181
|
+
data: { description: "" }
|
|
182
|
+
};
|
|
181
183
|
result.description = customSeo.description || homeSeoData.data.description;
|
|
182
184
|
}
|
|
183
185
|
|
|
@@ -197,26 +199,26 @@ function getSeoData(config, pageType, data, url = {}, seoConfig = {}) {
|
|
|
197
199
|
}
|
|
198
200
|
|
|
199
201
|
switch (pageType) {
|
|
200
|
-
case
|
|
201
|
-
return findRelevantConfig(
|
|
202
|
-
case
|
|
203
|
-
return findRelevantConfig(
|
|
204
|
-
case
|
|
205
|
-
return getSeoDataFromCollection(config, data) || getSeoData(config,
|
|
206
|
-
case
|
|
202
|
+
case "home-page":
|
|
203
|
+
return findRelevantConfig("home");
|
|
204
|
+
case "section-page":
|
|
205
|
+
return findRelevantConfig("section", lodash.get(data, ["data", "section", "id"])) || getSeoDataFromCollection(config, data) || getSeoData(config, "home-page", data, url);
|
|
206
|
+
case "collection-page":
|
|
207
|
+
return getSeoDataFromCollection(config, data) || getSeoData(config, "home-page", data, url);
|
|
208
|
+
case "tag-page":
|
|
207
209
|
return buildTagsFromTopic(config, lodash.get(data, ["data", "tag"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
208
|
-
case
|
|
210
|
+
case "story-page":
|
|
209
211
|
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
210
|
-
case
|
|
212
|
+
case "visual-story":
|
|
211
213
|
return buildTagsFromStory(config, lodash.get(data, ["story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
212
|
-
case
|
|
214
|
+
case "story-page-amp":
|
|
213
215
|
return buildTagsFromStory(config, lodash.get(data, ["data", "story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
214
|
-
case
|
|
216
|
+
case "author-page":
|
|
215
217
|
return buildTagsFromAuthor(config, lodash.get(data, ["data", "author"], {}), url, data) || getSeoData(config, "home-page", data, url);
|
|
216
|
-
case
|
|
218
|
+
case "shell":
|
|
217
219
|
return getShellSeoData(config);
|
|
218
220
|
default:
|
|
219
|
-
return getSeoData(config,
|
|
221
|
+
return getSeoData(config, "home-page", data, url);
|
|
220
222
|
}
|
|
221
223
|
}
|
|
222
224
|
|
|
@@ -226,15 +228,15 @@ function getSeoDataFromCollection(config, data) {
|
|
|
226
228
|
const customSeo = lodash.get(data, ["data", "customSeo"], {});
|
|
227
229
|
|
|
228
230
|
if (!summary) {
|
|
229
|
-
summary = (getSeoData(config,
|
|
231
|
+
summary = (getSeoData(config, "home-page", data) || {}).description;
|
|
230
232
|
}
|
|
231
233
|
const title = customSeo.title || name;
|
|
232
|
-
const pageTitle = customSeo[
|
|
234
|
+
const pageTitle = customSeo["page-title"] || name;
|
|
233
235
|
const ogTitle = customSeo.ogTitle || title;
|
|
234
236
|
const description = customSeo.description || summary;
|
|
235
237
|
const ogDescription = customSeo.ogDescription || summary;
|
|
236
238
|
return {
|
|
237
|
-
|
|
239
|
+
"page-title": pageTitle,
|
|
238
240
|
title,
|
|
239
241
|
ogTitle,
|
|
240
242
|
description,
|
|
@@ -244,7 +246,7 @@ function getSeoDataFromCollection(config, data) {
|
|
|
244
246
|
}
|
|
245
247
|
}
|
|
246
248
|
|
|
247
|
-
const SKIP_CANONICAL =
|
|
249
|
+
const SKIP_CANONICAL = "__SKIP__CANONICAL__";
|
|
248
250
|
|
|
249
251
|
/**
|
|
250
252
|
* TextTags adds the majority of basic tags, such as
|
|
@@ -268,42 +270,42 @@ function TextTags(seoConfig, config, pageType, data, { url }) {
|
|
|
268
270
|
|
|
269
271
|
if (!seoData) return [];
|
|
270
272
|
|
|
271
|
-
const currentUrl = `${config[
|
|
273
|
+
const currentUrl = `${config["sketches-host"]}${url.pathname}`;
|
|
272
274
|
|
|
273
275
|
const basicTags = {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
276
|
+
description: customSeo.description || seoData.description,
|
|
277
|
+
title: customSeo.title || seoData.title,
|
|
278
|
+
keywords: customSeo.keywords || seoData.keywords
|
|
277
279
|
};
|
|
278
280
|
|
|
279
281
|
const ogUrl = customSeo.ogUrl || seoData.ogUrl || seoData.canonicalUrl || currentUrl;
|
|
280
282
|
const ogTags = seoConfig.enableOgTags ? {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
"og:type": pageType === "story-page" || pageType === "story-page-amp" ? "article" : "website",
|
|
284
|
+
"og:url": ogUrl === SKIP_CANONICAL ? undefined : ogUrl,
|
|
285
|
+
"og:title": customSeo.ogTitle || seoData.ogTitle,
|
|
286
|
+
"og:description": customSeo.ogDescription || seoData.ogDescription
|
|
285
287
|
} : undefined;
|
|
286
288
|
|
|
287
289
|
const twitterTags = seoConfig.enableTwitterCards ? {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
290
|
+
"twitter:card": "summary_large_image",
|
|
291
|
+
"twitter:title": customSeo.twitterTitle || seoData.ogTitle,
|
|
292
|
+
"twitter:description": customSeo.twitterDescription || seoData.ogDescription
|
|
291
293
|
} : undefined;
|
|
292
294
|
|
|
293
295
|
const allTags = Object.assign(basicTags, ogTags, twitterTags);
|
|
294
296
|
|
|
295
|
-
const commonTags = [{ tag: "title", children: customSeo.title || data.title || seoData[
|
|
297
|
+
const commonTags = [{ tag: "title", children: customSeo.title || data.title || seoData["page-title"] }];
|
|
296
298
|
|
|
297
299
|
const canonical = seoData.canonicalUrl || currentUrl;
|
|
298
300
|
if (canonical != SKIP_CANONICAL) {
|
|
299
301
|
commonTags.push({ tag: "link", rel: "canonical", href: canonical });
|
|
300
302
|
}
|
|
301
303
|
|
|
302
|
-
if (pageType ===
|
|
304
|
+
if (pageType === "story-page" || pageType === "story-page-amp") {
|
|
303
305
|
commonTags.push({ name: "author", content: seoData.author });
|
|
304
306
|
}
|
|
305
307
|
|
|
306
|
-
if ((pageType ===
|
|
308
|
+
if ((pageType === "story-page" || pageType === "story-page-amp") && seoConfig.enableNews) {
|
|
307
309
|
commonTags.push({ name: "news_keywords", content: seoData.keywords });
|
|
308
310
|
if (lodash.get(data, ["data", "story", "seo", "meta-google-news-standout"])) commonTags.push({ tag: "link", rel: "standout", href: seoData.storyUrl || currentUrl });
|
|
309
311
|
}
|
|
@@ -319,7 +321,7 @@ function getTitle$1(seoConfig, config, pageType, data, params) {
|
|
|
319
321
|
if (lodash.get(data, ["data", "title"])) return customSeo.title || lodash.get(data, ["data", "title"]);
|
|
320
322
|
|
|
321
323
|
const seoData = getSeoData(config, pageType, data, undefined, seoConfig) || {};
|
|
322
|
-
return customSeo.title || seoData[
|
|
324
|
+
return customSeo.title || seoData["page-title"];
|
|
323
325
|
}
|
|
324
326
|
|
|
325
327
|
/**
|
package/package.json
CHANGED
package/src/text-tags.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { get, isEmpty } from
|
|
2
|
-
import { objectToTags } from
|
|
1
|
+
import { get, isEmpty } from "lodash";
|
|
2
|
+
import { objectToTags } from "./utils";
|
|
3
3
|
|
|
4
4
|
function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
5
|
-
if (!story)
|
|
6
|
-
return;
|
|
5
|
+
if (!story) return;
|
|
7
6
|
|
|
8
7
|
function getStoryCardMetadata(cardId) {
|
|
9
|
-
const { metadata = {} } = story.cards.find(card => card.id === cardId) || {};
|
|
10
|
-
const urlWithCardId = `${config[
|
|
8
|
+
const { metadata = {} } = story.cards.find((card) => card.id === cardId) || {};
|
|
9
|
+
const urlWithCardId = `${config["sketches-host"]}/${story.slug}?cardId=${cardId}`;
|
|
11
10
|
|
|
12
|
-
if (metadata && !isEmpty(metadata) && metadata[
|
|
11
|
+
if (metadata && !isEmpty(metadata) && metadata["social-share"]) {
|
|
13
12
|
return {
|
|
14
|
-
title: metadata[
|
|
15
|
-
description: metadata[
|
|
13
|
+
title: metadata["social-share"].title || story.headline,
|
|
14
|
+
description: metadata["social-share"].message || story.summary,
|
|
16
15
|
ogUrl: urlWithCardId,
|
|
17
|
-
ogTitle: metadata[
|
|
18
|
-
ogDescription: metadata[
|
|
16
|
+
ogTitle: metadata["social-share"].title || story.headline,
|
|
17
|
+
ogDescription: metadata["social-share"].message || story.summary,
|
|
19
18
|
};
|
|
20
19
|
}
|
|
21
20
|
return metadata;
|
|
@@ -23,16 +22,17 @@ function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
|
23
22
|
|
|
24
23
|
const seo = story.seo || {};
|
|
25
24
|
|
|
26
|
-
const storyUrl = story.url || `${config[
|
|
25
|
+
const storyUrl = story.url || `${config["sketches-host"]}/${story.slug}`;
|
|
27
26
|
|
|
28
27
|
const customSeo = get(data, ["data", "customSeo"], {});
|
|
29
|
-
const authors = get(story, [
|
|
28
|
+
const authors = get(story, ["authors"], []).map((author) => author.name);
|
|
30
29
|
const title = customSeo.title || seo["meta-title"] || story.headline;
|
|
31
30
|
const pageTitle = customSeo["page-title"] || seo["meta-title"] || story.headline;
|
|
32
31
|
const description = customSeo.description || seo["meta-description"] || story.summary;
|
|
33
|
-
const keywords = (customSeo.keywords || seo["meta-keywords"] || (story.tags || []).map(tag => tag.name)).join(",");
|
|
32
|
+
const keywords = (customSeo.keywords || seo["meta-keywords"] || (story.tags || []).map((tag) => tag.name)).join(",");
|
|
34
33
|
const ogUrl = customSeo.ogUrl || get(seo, ["og", "url"]) || storyUrl;
|
|
35
|
-
const getOgTitle =
|
|
34
|
+
const getOgTitle =
|
|
35
|
+
customSeo.ogTitle || get(story, ["alternative", "social", "default", "headline"], story.headline) || story.headline;
|
|
36
36
|
const ogDescription = customSeo.ogDescription || story.summary;
|
|
37
37
|
const storyMetaData = {
|
|
38
38
|
title,
|
|
@@ -44,7 +44,7 @@ function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
|
44
44
|
ogTitle: getOgTitle,
|
|
45
45
|
ogDescription,
|
|
46
46
|
storyUrl,
|
|
47
|
-
author: authors
|
|
47
|
+
author: authors,
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
if (url.query && url.query.cardId) {
|
|
@@ -56,16 +56,15 @@ function buildTagsFromStory(config, story, url = {}, data = {}) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
function buildTagsFromTopic(config, tag, url = {}, data) {
|
|
59
|
-
if (isEmpty(tag))
|
|
60
|
-
return;
|
|
59
|
+
if (isEmpty(tag)) return;
|
|
61
60
|
const customSeo = get(data, ["data", "customSeo"], {});
|
|
62
|
-
const tagName = customSeo.title || tag.name;
|
|
61
|
+
const tagName = customSeo.title || tag["meta-title"] || tag.name;
|
|
63
62
|
const pageTitle = customSeo["page-title"] || tagName;
|
|
64
|
-
const tagDescription = customSeo.description || tag[
|
|
65
|
-
const description = `Read stories listed under on ${
|
|
66
|
-
const tagUrl = `${config[
|
|
63
|
+
const tagDescription = customSeo.description || tag["meta-description"];
|
|
64
|
+
const description = `Read stories listed under on ${tag.name}`;
|
|
65
|
+
const tagUrl = `${config["sketches-host"]}${url.pathname}`;
|
|
67
66
|
const canonicalSlug = tag["canonical-slug"] || url.pathname;
|
|
68
|
-
const canonicalUrl = `${config[
|
|
67
|
+
const canonicalUrl = `${config["sketches-host"]}${canonicalSlug}`;
|
|
69
68
|
const ogTitle = customSeo.ogTitle || tagName;
|
|
70
69
|
const ogDescription = customSeo.ogDescription || description;
|
|
71
70
|
const topicMetaData = {
|
|
@@ -76,7 +75,7 @@ function buildTagsFromTopic(config, tag, url = {}, data) {
|
|
|
76
75
|
canonicalUrl,
|
|
77
76
|
ogUrl: tagUrl,
|
|
78
77
|
ogTitle,
|
|
79
|
-
ogDescription
|
|
78
|
+
ogDescription,
|
|
80
79
|
};
|
|
81
80
|
|
|
82
81
|
return topicMetaData;
|
|
@@ -85,19 +84,19 @@ function buildTagsFromTopic(config, tag, url = {}, data) {
|
|
|
85
84
|
function buildTagsFromAuthor(config, author, url = {}, data) {
|
|
86
85
|
if (isEmpty(author)) return;
|
|
87
86
|
|
|
88
|
-
const customSeo = get(data, ["data", "customSeo"], {})
|
|
87
|
+
const customSeo = get(data, ["data", "customSeo"], {});
|
|
89
88
|
const title = customSeo.title || author.name;
|
|
90
89
|
const pageTitle = customSeo["page-title"] || title;
|
|
91
90
|
const description = customSeo.description || author.bio || `View all articles written by ${title}`;
|
|
92
91
|
const ogTitle = customSeo.ogTitle || author.name;
|
|
93
|
-
const authorUrl = `${config[
|
|
92
|
+
const authorUrl = `${config["sketches-host"]}${url.pathname}`;
|
|
94
93
|
const ogDescription = customSeo.ogDescription || description;
|
|
95
94
|
|
|
96
95
|
return {
|
|
97
96
|
title,
|
|
98
97
|
"page-title": pageTitle,
|
|
99
98
|
description,
|
|
100
|
-
keywords: `${title},${config[
|
|
99
|
+
keywords: `${title},${config["publisher-name"]}`,
|
|
101
100
|
canonicalUrl: authorUrl,
|
|
102
101
|
ogUrl: authorUrl,
|
|
103
102
|
ogTitle,
|
|
@@ -105,7 +104,7 @@ function buildTagsFromAuthor(config, author, url = {}, data) {
|
|
|
105
104
|
};
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
function buildCustomTags(customTags = {}, pageType =
|
|
107
|
+
function buildCustomTags(customTags = {}, pageType = "") {
|
|
109
108
|
const configObject = customTags[pageType];
|
|
110
109
|
if (configObject) {
|
|
111
110
|
return configObject;
|
|
@@ -113,26 +112,32 @@ function buildCustomTags(customTags = {}, pageType = '') {
|
|
|
113
112
|
return {};
|
|
114
113
|
}
|
|
115
114
|
|
|
116
|
-
|
|
117
115
|
// The findRelevantConfig method call has no ownerId for home page.
|
|
118
116
|
// This causes the seoMetadata to be undefined.
|
|
119
117
|
// So the default value for the ownerId is set to null.
|
|
120
118
|
|
|
121
119
|
function getSeoData(config, pageType, data, url = {}, seoConfig = {}) {
|
|
122
120
|
function findRelevantConfig(ownerType, ownerId = null) {
|
|
123
|
-
const seoMetadata =
|
|
121
|
+
const seoMetadata =
|
|
122
|
+
config["seo-metadata"].find((page) => page["owner-type"] === ownerType && page["owner-id"] === ownerId) || {};
|
|
124
123
|
const { sections = [] } = config;
|
|
125
|
-
const section = sections.find(section => ownerType ==
|
|
126
|
-
const customSeo = get(data, ["data", "customSeo"], {})
|
|
124
|
+
const section = sections.find((section) => ownerType == "section" && section.id === ownerId) || {};
|
|
125
|
+
const customSeo = get(data, ["data", "customSeo"], {});
|
|
127
126
|
if (seoMetadata.data || section.id || !isEmpty(customSeo)) {
|
|
128
|
-
const result = Object.assign(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
127
|
+
const result = Object.assign(
|
|
128
|
+
{},
|
|
129
|
+
{
|
|
130
|
+
"page-title": customSeo["page-title"] || section.name,
|
|
131
|
+
title: customSeo.title || section.name,
|
|
132
|
+
canonicalUrl: customSeo["canonicalUrl"] || section["section-url"] || undefined,
|
|
133
|
+
},
|
|
134
|
+
seoMetadata.data
|
|
135
|
+
);
|
|
133
136
|
|
|
134
137
|
if (!result.description) {
|
|
135
|
-
const homeSeoData = config[
|
|
138
|
+
const homeSeoData = config["seo-metadata"].find((page) => page["owner-type"] === "home") || {
|
|
139
|
+
data: { description: "" },
|
|
140
|
+
};
|
|
136
141
|
result.description = customSeo.description || homeSeoData.data.description;
|
|
137
142
|
}
|
|
138
143
|
|
|
@@ -148,48 +153,73 @@ function getSeoData(config, pageType, data, url = {}, seoConfig = {}) {
|
|
|
148
153
|
|
|
149
154
|
function getShellSeoData(config) {
|
|
150
155
|
const seoMetadata = config["seo-metadata"].find((meta) => meta["owner-type"] === "home") || {};
|
|
151
|
-
return Object.assign({}, seoMetadata.data, { canonicalUrl: SKIP_CANONICAL }
|
|
156
|
+
return Object.assign({}, seoMetadata.data, { canonicalUrl: SKIP_CANONICAL });
|
|
152
157
|
}
|
|
153
158
|
|
|
154
159
|
switch (pageType) {
|
|
155
|
-
case
|
|
156
|
-
|
|
157
|
-
case
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
case
|
|
164
|
-
|
|
160
|
+
case "home-page":
|
|
161
|
+
return findRelevantConfig("home");
|
|
162
|
+
case "section-page":
|
|
163
|
+
return (
|
|
164
|
+
findRelevantConfig("section", get(data, ["data", "section", "id"])) ||
|
|
165
|
+
getSeoDataFromCollection(config, data) ||
|
|
166
|
+
getSeoData(config, "home-page", data, url)
|
|
167
|
+
);
|
|
168
|
+
case "collection-page":
|
|
169
|
+
return getSeoDataFromCollection(config, data) || getSeoData(config, "home-page", data, url);
|
|
170
|
+
case "tag-page":
|
|
171
|
+
return (
|
|
172
|
+
buildTagsFromTopic(config, get(data, ["data", "tag"]), url, data) || getSeoData(config, "home-page", data, url)
|
|
173
|
+
);
|
|
174
|
+
case "story-page":
|
|
175
|
+
return (
|
|
176
|
+
buildTagsFromStory(config, get(data, ["data", "story"]), url, data) ||
|
|
177
|
+
getSeoData(config, "home-page", data, url)
|
|
178
|
+
);
|
|
179
|
+
case "visual-story":
|
|
180
|
+
return buildTagsFromStory(config, get(data, ["story"]), url, data) || getSeoData(config, "home-page", data, url);
|
|
181
|
+
case "story-page-amp":
|
|
182
|
+
return (
|
|
183
|
+
buildTagsFromStory(config, get(data, ["data", "story"]), url, data) ||
|
|
184
|
+
getSeoData(config, "home-page", data, url)
|
|
185
|
+
);
|
|
186
|
+
case "author-page":
|
|
187
|
+
return (
|
|
188
|
+
buildTagsFromAuthor(config, get(data, ["data", "author"], {}), url, data) ||
|
|
189
|
+
getSeoData(config, "home-page", data, url)
|
|
190
|
+
);
|
|
191
|
+
case "shell":
|
|
192
|
+
return getShellSeoData(config);
|
|
193
|
+
default:
|
|
194
|
+
return getSeoData(config, "home-page", data, url);
|
|
165
195
|
}
|
|
166
196
|
}
|
|
167
197
|
|
|
168
198
|
function getSeoDataFromCollection(config, data) {
|
|
169
199
|
if (get(data, ["data", "collection", "name"])) {
|
|
170
200
|
let { name, summary } = get(data, ["data", "collection"]);
|
|
171
|
-
const customSeo = get(data, ["data", "customSeo"], {})
|
|
201
|
+
const customSeo = get(data, ["data", "customSeo"], {});
|
|
172
202
|
|
|
173
203
|
if (!summary) {
|
|
174
|
-
summary = (getSeoData(config,
|
|
204
|
+
summary = (getSeoData(config, "home-page", data) || {}).description;
|
|
175
205
|
}
|
|
176
206
|
const title = customSeo.title || name;
|
|
177
|
-
const pageTitle = customSeo[
|
|
207
|
+
const pageTitle = customSeo["page-title"] || name;
|
|
178
208
|
const ogTitle = customSeo.ogTitle || title;
|
|
179
209
|
const description = customSeo.description || summary;
|
|
180
210
|
const ogDescription = customSeo.ogDescription || summary;
|
|
181
211
|
return {
|
|
182
|
-
|
|
212
|
+
"page-title": pageTitle,
|
|
183
213
|
title,
|
|
184
214
|
ogTitle,
|
|
185
215
|
description,
|
|
186
216
|
ogDescription,
|
|
187
|
-
canonicalUrl: SKIP_CANONICAL
|
|
188
|
-
}
|
|
217
|
+
canonicalUrl: SKIP_CANONICAL,
|
|
218
|
+
};
|
|
189
219
|
}
|
|
190
220
|
}
|
|
191
221
|
|
|
192
|
-
const SKIP_CANONICAL =
|
|
222
|
+
const SKIP_CANONICAL = "__SKIP__CANONICAL__";
|
|
193
223
|
|
|
194
224
|
/**
|
|
195
225
|
* TextTags adds the majority of basic tags, such as
|
|
@@ -209,49 +239,50 @@ const SKIP_CANONICAL = '__SKIP__CANONICAL__'
|
|
|
209
239
|
*/
|
|
210
240
|
export function TextTags(seoConfig, config, pageType, data, { url }) {
|
|
211
241
|
const seoData = getSeoData(config, pageType, data, url, seoConfig);
|
|
212
|
-
const customSeo = get(data, ["data", "customSeo"], {})
|
|
242
|
+
const customSeo = get(data, ["data", "customSeo"], {});
|
|
213
243
|
|
|
214
|
-
if (!seoData)
|
|
215
|
-
return [];
|
|
244
|
+
if (!seoData) return [];
|
|
216
245
|
|
|
217
|
-
const currentUrl = `${config[
|
|
246
|
+
const currentUrl = `${config["sketches-host"]}${url.pathname}`;
|
|
218
247
|
|
|
219
248
|
const basicTags = {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
249
|
+
description: customSeo.description || seoData.description,
|
|
250
|
+
title: customSeo.title || seoData.title,
|
|
251
|
+
keywords: customSeo.keywords || seoData.keywords,
|
|
223
252
|
};
|
|
224
253
|
|
|
225
254
|
const ogUrl = customSeo.ogUrl || seoData.ogUrl || seoData.canonicalUrl || currentUrl;
|
|
226
|
-
const ogTags = seoConfig.enableOgTags
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
255
|
+
const ogTags = seoConfig.enableOgTags
|
|
256
|
+
? {
|
|
257
|
+
"og:type": pageType === "story-page" || pageType === "story-page-amp" ? "article" : "website",
|
|
258
|
+
"og:url": ogUrl === SKIP_CANONICAL ? undefined : ogUrl,
|
|
259
|
+
"og:title": customSeo.ogTitle || seoData.ogTitle,
|
|
260
|
+
"og:description": customSeo.ogDescription || seoData.ogDescription,
|
|
261
|
+
}
|
|
262
|
+
: undefined;
|
|
263
|
+
|
|
264
|
+
const twitterTags = seoConfig.enableTwitterCards
|
|
265
|
+
? {
|
|
266
|
+
"twitter:card": "summary_large_image",
|
|
267
|
+
"twitter:title": customSeo.twitterTitle || seoData.ogTitle,
|
|
268
|
+
"twitter:description": customSeo.twitterDescription || seoData.ogDescription,
|
|
269
|
+
}
|
|
270
|
+
: undefined;
|
|
238
271
|
|
|
239
272
|
const allTags = Object.assign(basicTags, ogTags, twitterTags);
|
|
240
273
|
|
|
241
|
-
const commonTags = [
|
|
242
|
-
{ tag: "title", children: customSeo.title || data.title || seoData['page-title'] },
|
|
243
|
-
];
|
|
274
|
+
const commonTags = [{ tag: "title", children: customSeo.title || data.title || seoData["page-title"] }];
|
|
244
275
|
|
|
245
276
|
const canonical = seoData.canonicalUrl || currentUrl;
|
|
246
277
|
if (canonical != SKIP_CANONICAL) {
|
|
247
278
|
commonTags.push({ tag: "link", rel: "canonical", href: canonical });
|
|
248
279
|
}
|
|
249
280
|
|
|
250
|
-
if (pageType ===
|
|
281
|
+
if (pageType === "story-page" || pageType === "story-page-amp") {
|
|
251
282
|
commonTags.push({ name: "author", content: seoData.author });
|
|
252
283
|
}
|
|
253
284
|
|
|
254
|
-
if ((pageType ===
|
|
285
|
+
if ((pageType === "story-page" || pageType === "story-page-amp") && seoConfig.enableNews) {
|
|
255
286
|
commonTags.push({ name: "news_keywords", content: seoData.keywords });
|
|
256
287
|
if (get(data, ["data", "story", "seo", "meta-google-news-standout"]))
|
|
257
288
|
commonTags.push({ tag: "link", rel: "standout", href: seoData.storyUrl || currentUrl });
|
|
@@ -261,14 +292,12 @@ export function TextTags(seoConfig, config, pageType, data, { url }) {
|
|
|
261
292
|
}
|
|
262
293
|
|
|
263
294
|
export function getTitle(seoConfig, config, pageType, data, params) {
|
|
264
|
-
const customSeo = get(data, ["data", "customSeo"], {})
|
|
295
|
+
const customSeo = get(data, ["data", "customSeo"], {});
|
|
265
296
|
|
|
266
|
-
if (get(data, ["title"]))
|
|
267
|
-
return customSeo.title || get(data, ["title"]);
|
|
297
|
+
if (get(data, ["title"])) return customSeo.title || get(data, ["title"]);
|
|
268
298
|
|
|
269
|
-
if (get(data, ["data", "title"]))
|
|
270
|
-
return customSeo.title || get(data, ["data", "title"]);
|
|
299
|
+
if (get(data, ["data", "title"])) return customSeo.title || get(data, ["data", "title"]);
|
|
271
300
|
|
|
272
301
|
const seoData = getSeoData(config, pageType, data, undefined, seoConfig) || {};
|
|
273
|
-
return customSeo.title || seoData[
|
|
274
|
-
}
|
|
302
|
+
return customSeo.title || seoData["page-title"];
|
|
303
|
+
}
|