@quintype/seo 1.41.1 → 1.41.3-gsc-errors-fix.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/CHANGELOG.md +2 -0
- package/dist/index.cjs.js +47 -20
- package/package.json +1 -1
- package/src/amp-tags.js +2 -2
- package/src/author-tags.js +22 -7
- package/src/generate-common-seo.js +42 -28
- package/test/amp_tags_test.js +2 -8
- package/test/author_tags_test.js +106 -0
- package/test/generate_common_seo_test.js +202 -118
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
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.41.2](https://github.com/quintype/quintype-node-seo/compare/v1.41.1...v1.41.2) (2022-11-30)
|
|
6
|
+
|
|
5
7
|
### [1.41.1](https://github.com/quintype/quintype-node-seo/compare/v1.41.1-gsc-errors.0...v1.41.1) (2022-11-29)
|
|
6
8
|
|
|
7
9
|
## [1.41.0](https://github.com/quintype/quintype-node-seo/compare/v1.40.15...v1.41.0) (2022-11-29)
|
package/dist/index.cjs.js
CHANGED
|
@@ -81,13 +81,14 @@ const getDomain = (url, domainSlug) => {
|
|
|
81
81
|
* @param {...*} params See {@link Generator} for other Parameters
|
|
82
82
|
*/
|
|
83
83
|
function StoryAmpTags(seoConfig, config, pageType, data = {}, opts) {
|
|
84
|
+
const templatesToIgnore = seoConfig.ignoreAmpHtmlStoryTemplates || ["visual-story"];
|
|
84
85
|
const story = get__default["default"](data, ["data", "story"], {});
|
|
85
86
|
const { currentHostUrl = "", domainSlug } = data;
|
|
86
87
|
// TODO: Remove this condition and always make absolute URL if that's better for AMP discoverability.
|
|
87
88
|
const ampUrlAppend = seoConfig.appendHostToAmpUrl ? getDomain(currentHostUrl, domainSlug) || config["sketches-host"] : "";
|
|
88
89
|
const storySlug = seoConfig.decodeAmpUrl ? decodeURIComponent(story.slug) : encodeURIComponent(story.slug);
|
|
89
90
|
const ampUrl = story["story-template"] === "visual-story" ? `${ampUrlAppend}/${storySlug}` : `${ampUrlAppend}/amp/story/${storySlug}`;
|
|
90
|
-
const ignoreStoryTemplate =
|
|
91
|
+
const ignoreStoryTemplate = templatesToIgnore.includes(story["story-template"]);
|
|
91
92
|
if (showAmpTag(seoConfig, pageType, story) && !ignoreStoryTemplate) {
|
|
92
93
|
return [{
|
|
93
94
|
tag: "link",
|
|
@@ -106,13 +107,28 @@ function StoryAmpTags(seoConfig, config, pageType, data = {}, opts) {
|
|
|
106
107
|
* @param {*} seoConfig
|
|
107
108
|
* @param {...*} params See {@link Generator} for other Parameters
|
|
108
109
|
*/
|
|
109
|
-
function AuthorTags(seoConfig, config, pageType, data, { url }) {
|
|
110
|
-
if (pageType != "story-page" || pageType != "story-page-amp") return [];
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
function AuthorTags(seoConfig, config, pageType, data, { url }) {
|
|
112
|
+
if (pageType === "story-page" || pageType === "story-page-amp") {
|
|
113
|
+
return [{
|
|
114
|
+
name: "twitter:creator",
|
|
115
|
+
content: getTwitterCreator(data)
|
|
116
|
+
}];
|
|
117
|
+
}
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function getTwitterCreator(storyData) {
|
|
122
|
+
const twitterData = lodash.get(storyData, ["data", "story", "authors", 0, "social", "twitter"], {});
|
|
123
|
+
const twitterUrl = twitterData.url || "";
|
|
124
|
+
const twitterHandle = twitterData.handle || "";
|
|
125
|
+
if (twitterHandle.startsWith("@")) return twitterHandle;
|
|
126
|
+
const twitterHandleFromUrl = twitterUrl.split("/").pop();
|
|
127
|
+
if (twitterHandleFromUrl) {
|
|
128
|
+
if (twitterHandleFromUrl.startsWith("@")) return twitterHandleFromUrl;
|
|
129
|
+
return `@${twitterHandleFromUrl}`;
|
|
130
|
+
}
|
|
131
|
+
return lodash.get(storyData, ["data", "story", "author-name"]);
|
|
116
132
|
}
|
|
117
133
|
|
|
118
134
|
function getTitle$1(config) {
|
|
@@ -122,9 +138,10 @@ function getTitle$1(config) {
|
|
|
122
138
|
function generateStaticData(config) {
|
|
123
139
|
const title = getTitle$1(config);
|
|
124
140
|
const themeConfig = config["theme-attributes"] || {};
|
|
125
|
-
const publicIntegrations = get__default["default"](config, [
|
|
141
|
+
const publicIntegrations = get__default["default"](config, ["public-integrations"], {});
|
|
142
|
+
const siteTwitterHandle = getSiteTwitterHandle(config, title);
|
|
126
143
|
const staticData = {
|
|
127
|
-
"twitter:site":
|
|
144
|
+
"twitter:site": siteTwitterHandle,
|
|
128
145
|
"twitter:domain": config["sketches-host"],
|
|
129
146
|
"twitter:app:name:ipad": themeConfig["twitter_app_name_ipad"],
|
|
130
147
|
"twitter:app:name:googleplay": themeConfig["twitter_app_name_googleplay"],
|
|
@@ -133,7 +150,7 @@ function generateStaticData(config) {
|
|
|
133
150
|
"twitter:app:id:iphone": themeConfig["twitter_app_id_iphone"],
|
|
134
151
|
"apple-itunes-app": themeConfig["apple_itunes_app"],
|
|
135
152
|
"google-play-app": themeConfig["google_play_app"],
|
|
136
|
-
"fb:app_id": get__default["default"](publicIntegrations, [
|
|
153
|
+
"fb:app_id": get__default["default"](publicIntegrations, ["facebook", "app-id"]) || get__default["default"](themeConfig, ["fb_app_id"]),
|
|
137
154
|
"fb:pages": themeConfig["fb_pages"],
|
|
138
155
|
"og:site_name": title
|
|
139
156
|
};
|
|
@@ -146,12 +163,12 @@ function generateImageObject(config = {}) {
|
|
|
146
163
|
return {
|
|
147
164
|
"@context": "http://schema.org",
|
|
148
165
|
"@type": "ImageObject",
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
166
|
+
author: config["publisher-name"],
|
|
167
|
+
contentUrl: themeConfig.logo,
|
|
168
|
+
url: themeConfig.logo,
|
|
169
|
+
name: "logo",
|
|
170
|
+
width: themeConfig.logo && getQueryParams(themeConfig.logo).width,
|
|
171
|
+
height: themeConfig.logo && getQueryParams(themeConfig.logo).height
|
|
155
172
|
};
|
|
156
173
|
}
|
|
157
174
|
|
|
@@ -163,8 +180,8 @@ function generateStructuredData(config = {}) {
|
|
|
163
180
|
if (!themeConfig || !themeConfig.logo) {
|
|
164
181
|
return {};
|
|
165
182
|
}
|
|
166
|
-
let enableStructuredDataForNewsArticle = themeConfig[
|
|
167
|
-
if (config.hasOwnProperty(
|
|
183
|
+
let enableStructuredDataForNewsArticle = themeConfig["structured_data_news_article"] || false;
|
|
184
|
+
if (config.hasOwnProperty("enableStructuredDataForNewsArticle") && typeof config.enableStructuredDataForNewsArticle !== "undefined") {
|
|
168
185
|
enableStructuredDataForNewsArticle = config.enableStructuredDataForNewsArticle;
|
|
169
186
|
}
|
|
170
187
|
|
|
@@ -177,8 +194,8 @@ function generateStructuredData(config = {}) {
|
|
|
177
194
|
},
|
|
178
195
|
enableNewsArticle: !!enableStructuredDataForNewsArticle,
|
|
179
196
|
storyUrlAsMainEntityUrl: !!enableStructuredDataForNewsArticle,
|
|
180
|
-
enableVideo: !themeConfig[
|
|
181
|
-
enableLiveBlog: !themeConfig[
|
|
197
|
+
enableVideo: !themeConfig["structured_data_enable_video"],
|
|
198
|
+
enableLiveBlog: !themeConfig["structured_data_enable_live_blog"],
|
|
182
199
|
website: {
|
|
183
200
|
url: config["sketches-host"],
|
|
184
201
|
searchpath: "search?q={query}",
|
|
@@ -190,6 +207,16 @@ function generateStructuredData(config = {}) {
|
|
|
190
207
|
};
|
|
191
208
|
}
|
|
192
209
|
|
|
210
|
+
function getSiteTwitterHandle(config, fallback) {
|
|
211
|
+
const twitterUrl = get__default["default"](config, ["social-links", "twitter-url"], "");
|
|
212
|
+
const twitterHandleFromUrl = twitterUrl.split("/").pop();
|
|
213
|
+
if (twitterHandleFromUrl) {
|
|
214
|
+
if (twitterHandleFromUrl.startsWith("@")) return twitterHandleFromUrl;
|
|
215
|
+
return `@${twitterHandleFromUrl}`;
|
|
216
|
+
}
|
|
217
|
+
return fallback;
|
|
218
|
+
}
|
|
219
|
+
|
|
193
220
|
function pickImageFromCard(story, cardId) {
|
|
194
221
|
const { metadata = {} } = story.cards.find(card => card.id === cardId) || {};
|
|
195
222
|
if (metadata && !lodash.isEmpty(metadata) && lodash.get(metadata, ["social-share", "image", "key"], false)) {
|
package/package.json
CHANGED
package/src/amp-tags.js
CHANGED
|
@@ -33,6 +33,7 @@ const getDomain = (url, domainSlug) => {
|
|
|
33
33
|
* @param {...*} params See {@link Generator} for other Parameters
|
|
34
34
|
*/
|
|
35
35
|
export function StoryAmpTags(seoConfig, config, pageType, data = {}, opts) {
|
|
36
|
+
const templatesToIgnore = seoConfig.ignoreAmpHtmlStoryTemplates || ["visual-story"];
|
|
36
37
|
const story = get(data, ["data", "story"], {});
|
|
37
38
|
const { currentHostUrl = "", domainSlug } = data;
|
|
38
39
|
// TODO: Remove this condition and always make absolute URL if that's better for AMP discoverability.
|
|
@@ -44,8 +45,7 @@ export function StoryAmpTags(seoConfig, config, pageType, data = {}, opts) {
|
|
|
44
45
|
story["story-template"] === "visual-story"
|
|
45
46
|
? `${ampUrlAppend}/${storySlug}`
|
|
46
47
|
: `${ampUrlAppend}/amp/story/${storySlug}`;
|
|
47
|
-
const ignoreStoryTemplate =
|
|
48
|
-
seoConfig.ignoreAmpHtmlStoryTemplates && seoConfig.ignoreAmpHtmlStoryTemplates.includes(story["story-template"]);
|
|
48
|
+
const ignoreStoryTemplate = templatesToIgnore.includes(story["story-template"]);
|
|
49
49
|
if (showAmpTag(seoConfig, pageType, story) && !ignoreStoryTemplate) {
|
|
50
50
|
return [
|
|
51
51
|
{
|
package/src/author-tags.js
CHANGED
|
@@ -7,13 +7,28 @@ import { get } from "lodash";
|
|
|
7
7
|
* @param {*} seoConfig
|
|
8
8
|
* @param {...*} params See {@link Generator} for other Parameters
|
|
9
9
|
*/
|
|
10
|
+
|
|
10
11
|
export function AuthorTags(seoConfig, config, pageType, data, { url }) {
|
|
11
|
-
if (pageType
|
|
12
|
+
if (pageType === "story-page" || pageType === "story-page-amp") {
|
|
13
|
+
return [
|
|
14
|
+
{
|
|
15
|
+
name: "twitter:creator",
|
|
16
|
+
content: getTwitterCreator(data),
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
12
22
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
function getTwitterCreator(storyData) {
|
|
24
|
+
const twitterData = get(storyData, ["data", "story", "authors", 0, "social", "twitter"], {});
|
|
25
|
+
const twitterUrl = twitterData.url || "";
|
|
26
|
+
const twitterHandle = twitterData.handle || "";
|
|
27
|
+
if (twitterHandle.startsWith("@")) return twitterHandle;
|
|
28
|
+
const twitterHandleFromUrl = twitterUrl.split("/").pop();
|
|
29
|
+
if (twitterHandleFromUrl) {
|
|
30
|
+
if (twitterHandleFromUrl.startsWith("@")) return twitterHandleFromUrl;
|
|
31
|
+
return `@${twitterHandleFromUrl}`;
|
|
32
|
+
}
|
|
33
|
+
return get(storyData, ["data", "story", "author-name"]);
|
|
19
34
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import get from
|
|
2
|
-
import isUndefined from
|
|
3
|
-
import omitBy from
|
|
1
|
+
import get from "lodash/get";
|
|
2
|
+
import isUndefined from "lodash/isUndefined";
|
|
3
|
+
import omitBy from "lodash/omitBy";
|
|
4
4
|
import { getQueryParams } from "./utils";
|
|
5
5
|
|
|
6
6
|
export function getTitle(config) {
|
|
@@ -10,9 +10,10 @@ export function getTitle(config) {
|
|
|
10
10
|
export function generateStaticData(config) {
|
|
11
11
|
const title = getTitle(config);
|
|
12
12
|
const themeConfig = config["theme-attributes"] || {};
|
|
13
|
-
const publicIntegrations = get(config, [
|
|
13
|
+
const publicIntegrations = get(config, ["public-integrations"], {});
|
|
14
|
+
const siteTwitterHandle = getSiteTwitterHandle(config, title);
|
|
14
15
|
const staticData = {
|
|
15
|
-
"twitter:site":
|
|
16
|
+
"twitter:site": siteTwitterHandle,
|
|
16
17
|
"twitter:domain": config["sketches-host"],
|
|
17
18
|
"twitter:app:name:ipad": themeConfig["twitter_app_name_ipad"],
|
|
18
19
|
"twitter:app:name:googleplay": themeConfig["twitter_app_name_googleplay"],
|
|
@@ -21,38 +22,41 @@ export function generateStaticData(config) {
|
|
|
21
22
|
"twitter:app:id:iphone": themeConfig["twitter_app_id_iphone"],
|
|
22
23
|
"apple-itunes-app": themeConfig["apple_itunes_app"],
|
|
23
24
|
"google-play-app": themeConfig["google_play_app"],
|
|
24
|
-
"fb:app_id": get(publicIntegrations, [
|
|
25
|
+
"fb:app_id": get(publicIntegrations, ["facebook", "app-id"]) || get(themeConfig, ["fb_app_id"]),
|
|
25
26
|
"fb:pages": themeConfig["fb_pages"],
|
|
26
|
-
"og:site_name": title
|
|
27
|
+
"og:site_name": title,
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
return omitBy(staticData, isUndefined);
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export function generateImageObject(config = {}) {
|
|
33
|
-
const {"theme-attributes": themeConfig = {}} = config;
|
|
34
|
-
return
|
|
34
|
+
const { "theme-attributes": themeConfig = {} } = config;
|
|
35
|
+
return {
|
|
35
36
|
"@context": "http://schema.org",
|
|
36
37
|
"@type": "ImageObject",
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
38
|
+
author: config["publisher-name"],
|
|
39
|
+
contentUrl: themeConfig.logo,
|
|
40
|
+
url: themeConfig.logo,
|
|
41
|
+
name: "logo",
|
|
42
|
+
width: themeConfig.logo && getQueryParams(themeConfig.logo).width,
|
|
43
|
+
height: themeConfig.logo && getQueryParams(themeConfig.logo).height,
|
|
44
|
+
};
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
export function generateStructuredData(config = {}) {
|
|
47
48
|
const title = getTitle(config);
|
|
48
|
-
const { "theme-attributes":themeConfig, "social-links":socialLinks, "seo-metadata":seoMetadata = [] } = config;
|
|
49
|
-
const homePageSeo = seoMetadata.find(page => page["owner-type"] === "home") || {};
|
|
50
|
-
const { "page-title":pageTitle = "", description = "", keywords
|
|
51
|
-
if(!themeConfig || !themeConfig.logo) {
|
|
49
|
+
const { "theme-attributes": themeConfig, "social-links": socialLinks, "seo-metadata": seoMetadata = [] } = config;
|
|
50
|
+
const homePageSeo = seoMetadata.find((page) => page["owner-type"] === "home") || {};
|
|
51
|
+
const { "page-title": pageTitle = "", description = "", keywords = "" } = get(homePageSeo, ["data"], {});
|
|
52
|
+
if (!themeConfig || !themeConfig.logo) {
|
|
52
53
|
return {};
|
|
53
54
|
}
|
|
54
|
-
let enableStructuredDataForNewsArticle = themeConfig[
|
|
55
|
-
if(
|
|
55
|
+
let enableStructuredDataForNewsArticle = themeConfig["structured_data_news_article"] || false;
|
|
56
|
+
if (
|
|
57
|
+
config.hasOwnProperty("enableStructuredDataForNewsArticle") &&
|
|
58
|
+
typeof config.enableStructuredDataForNewsArticle !== "undefined"
|
|
59
|
+
) {
|
|
56
60
|
enableStructuredDataForNewsArticle = config.enableStructuredDataForNewsArticle;
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -61,19 +65,29 @@ export function generateStructuredData(config = {}) {
|
|
|
61
65
|
name: title,
|
|
62
66
|
url: config["sketches-host"],
|
|
63
67
|
logo: generateImageObject(config),
|
|
64
|
-
sameAs: socialLinks ? Object.values(socialLinks) : []
|
|
68
|
+
sameAs: socialLinks ? Object.values(socialLinks) : [],
|
|
65
69
|
},
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
enableVideo: !themeConfig[
|
|
69
|
-
enableLiveBlog: !themeConfig[
|
|
70
|
+
enableNewsArticle: !!enableStructuredDataForNewsArticle,
|
|
71
|
+
storyUrlAsMainEntityUrl: !!enableStructuredDataForNewsArticle,
|
|
72
|
+
enableVideo: !themeConfig["structured_data_enable_video"],
|
|
73
|
+
enableLiveBlog: !themeConfig["structured_data_enable_live_blog"],
|
|
70
74
|
website: {
|
|
71
75
|
url: config["sketches-host"],
|
|
72
76
|
searchpath: "search?q={query}",
|
|
73
77
|
queryinput: "required name=query",
|
|
74
78
|
name: pageTitle || title,
|
|
75
79
|
headline: description,
|
|
76
|
-
keywords
|
|
80
|
+
keywords,
|
|
77
81
|
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getSiteTwitterHandle(config, fallback) {
|
|
86
|
+
const twitterUrl = get(config, ["social-links", "twitter-url"], "");
|
|
87
|
+
const twitterHandleFromUrl = twitterUrl.split("/").pop();
|
|
88
|
+
if (twitterHandleFromUrl) {
|
|
89
|
+
if (twitterHandleFromUrl.startsWith("@")) return twitterHandleFromUrl;
|
|
90
|
+
return `@${twitterHandleFromUrl}`;
|
|
78
91
|
}
|
|
92
|
+
return fallback;
|
|
79
93
|
}
|
package/test/amp_tags_test.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const { StoryAmpTags } = require("..");
|
|
2
2
|
const { getSeoMetadata, assertContains } = require("./utils");
|
|
3
3
|
|
|
4
|
-
const assert = require(
|
|
4
|
+
const assert = require("assert");
|
|
5
5
|
|
|
6
|
-
describe(
|
|
6
|
+
describe("AmpTags", function () {
|
|
7
7
|
const seoConfig = {
|
|
8
8
|
generators: [StoryAmpTags],
|
|
9
9
|
ampStoryPages: true,
|
|
@@ -19,12 +19,6 @@ describe('AmpTags', function () {
|
|
|
19
19
|
assertContains('<link rel="amphtml" href="/amp/story/section%2Fslug"/>', string);
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
it("it does not append `/amp/story` to the amp tag when it's a visual story", function () {
|
|
23
|
-
const story = { slug: "section/slug", "is-amp-supported": true };
|
|
24
|
-
const string = getSeoMetadata(seoConfig, config, "story-page", { data: { story: { ...story, "story-template": "visual-story" } } }, {});
|
|
25
|
-
assertContains('<link rel="amphtml" href="/section%2Fslug"/>', string);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
22
|
it("does not rely on is-amp-supported in story API", function () {
|
|
29
23
|
const story = { slug: "section/slug", "is-amp-supported": false };
|
|
30
24
|
const string = getSeoMetadata(seoConfig, config, "story-page", { data: { story: story } }, {});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
const { AuthorTags } = require("..");
|
|
2
|
+
const { getSeoMetadata } = require("./utils");
|
|
3
|
+
const assert = require("assert");
|
|
4
|
+
|
|
5
|
+
describe("AuthorTags", function () {
|
|
6
|
+
it("should take twitter handle of author if present", function () {
|
|
7
|
+
const storyPageMockData = {
|
|
8
|
+
data: {
|
|
9
|
+
story: {
|
|
10
|
+
"author-name": "John Doe",
|
|
11
|
+
authors: [
|
|
12
|
+
{
|
|
13
|
+
slug: "john-doe",
|
|
14
|
+
social: {
|
|
15
|
+
twitter: {
|
|
16
|
+
url: "https://twitter.com/JohnDoe123",
|
|
17
|
+
handle: "@JohnDoe123",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
name: "John Doe",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
const seoConfig = {
|
|
27
|
+
generators: [AuthorTags],
|
|
28
|
+
};
|
|
29
|
+
const string = getSeoMetadata(seoConfig, {}, "story-page", storyPageMockData, {});
|
|
30
|
+
assert.equal('<meta name="twitter:creator" content="@JohnDoe123"/>', string);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("should generate twitter handle from url if twitter handle is not present", function () {
|
|
34
|
+
const storyPageMockData = {
|
|
35
|
+
data: {
|
|
36
|
+
story: {
|
|
37
|
+
"author-name": "John Doe",
|
|
38
|
+
authors: [
|
|
39
|
+
{
|
|
40
|
+
slug: "john-doe",
|
|
41
|
+
social: {
|
|
42
|
+
twitter: {
|
|
43
|
+
url: "https://twitter.com/JohnDoe123",
|
|
44
|
+
handle: "",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
name: "John Doe",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
const seoConfig = {
|
|
54
|
+
generators: [AuthorTags],
|
|
55
|
+
};
|
|
56
|
+
const string = getSeoMetadata(seoConfig, {}, "story-page", storyPageMockData, {});
|
|
57
|
+
assert.equal('<meta name="twitter:creator" content="@JohnDoe123"/>', string);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should correctly generate twitter handle from url", function () {
|
|
61
|
+
const storyPageMockData = {
|
|
62
|
+
data: {
|
|
63
|
+
story: {
|
|
64
|
+
"author-name": "John Doe",
|
|
65
|
+
authors: [
|
|
66
|
+
{
|
|
67
|
+
slug: "john-doe",
|
|
68
|
+
social: {
|
|
69
|
+
twitter: {
|
|
70
|
+
url: "https://twitter.com/@JohnDoe123",
|
|
71
|
+
handle: "",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
name: "John Doe",
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
const seoConfig = {
|
|
81
|
+
generators: [AuthorTags],
|
|
82
|
+
};
|
|
83
|
+
const string = getSeoMetadata(seoConfig, {}, "story-page", storyPageMockData, {});
|
|
84
|
+
assert.equal('<meta name="twitter:creator" content="@JohnDoe123"/>', string);
|
|
85
|
+
});
|
|
86
|
+
it("should take author name for twitter:creator if no twitter data about author is present", function () {
|
|
87
|
+
const storyPageMockData = {
|
|
88
|
+
data: {
|
|
89
|
+
story: {
|
|
90
|
+
"author-name": "John Doe",
|
|
91
|
+
authors: [
|
|
92
|
+
{
|
|
93
|
+
slug: "john-doe",
|
|
94
|
+
name: "John Doe",
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
const seoConfig = {
|
|
101
|
+
generators: [AuthorTags],
|
|
102
|
+
};
|
|
103
|
+
const string = getSeoMetadata(seoConfig, {}, "story-page", storyPageMockData, {});
|
|
104
|
+
assert.equal('<meta name="twitter:creator" content="John Doe"/>', string);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
const assert = require("assert");
|
|
2
|
-
const {generateStaticData, generateStructuredData} = require("..");
|
|
2
|
+
const { generateStaticData, generateStructuredData } = require("..");
|
|
3
3
|
|
|
4
|
-
describe(
|
|
5
|
-
describe(
|
|
6
|
-
it(
|
|
4
|
+
describe("Seo Helpers", function () {
|
|
5
|
+
describe("Static Data Generator", function () {
|
|
6
|
+
it("generates static data", function () {
|
|
7
7
|
const config = {
|
|
8
8
|
"public-integrations": {
|
|
9
|
-
|
|
10
|
-
"app-id": "4"
|
|
11
|
-
}
|
|
9
|
+
facebook: {
|
|
10
|
+
"app-id": "4",
|
|
11
|
+
},
|
|
12
12
|
},
|
|
13
13
|
"publisher-settings": {
|
|
14
|
-
|
|
14
|
+
title: "abc",
|
|
15
15
|
},
|
|
16
16
|
"sketches-host": "abc.com",
|
|
17
17
|
"publisher-name": "Abc",
|
|
18
18
|
"theme-attributes": {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
}
|
|
19
|
+
twitter_app_name_ipad: "twitter-app-name-ipad",
|
|
20
|
+
twitter_app_name_googleplay: "twitter-app-name-googleplay",
|
|
21
|
+
twitter_app_id_googleplay: "twitter-app-id-googleplay",
|
|
22
|
+
twitter_app_name_iphone: "twitter-app-name-iphone",
|
|
23
|
+
twitter_app_id_iphone: "twitter-app-id-phone",
|
|
24
|
+
apple_itunes_app: "apple-itunes-app",
|
|
25
|
+
google_play_app: "google-play-app",
|
|
26
|
+
fb_app_id: "fb-app-id",
|
|
27
|
+
fb_pages: "fb-pages",
|
|
28
|
+
logo: "https://quintype.com/abc.png",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
31
|
const expectedStaticData = {
|
|
32
32
|
"twitter:site": "abc",
|
|
33
33
|
"twitter:domain": "abc.com",
|
|
@@ -40,82 +40,93 @@ describe('Seo Helpers', function() {
|
|
|
40
40
|
"google-play-app": "google-play-app",
|
|
41
41
|
"fb:app_id": "4",
|
|
42
42
|
"fb:pages": "fb-pages",
|
|
43
|
-
"og:site_name": "abc"
|
|
43
|
+
"og:site_name": "abc",
|
|
44
44
|
};
|
|
45
45
|
const actualStaticData = generateStaticData(config);
|
|
46
|
-
assert.deepEqual(actualStaticData, expectedStaticData)
|
|
46
|
+
assert.deepEqual(actualStaticData, expectedStaticData);
|
|
47
47
|
});
|
|
48
|
-
|
|
49
|
-
it(
|
|
48
|
+
|
|
49
|
+
it("does not crash when the config is empty", function () {
|
|
50
50
|
const actualStaticData = generateStaticData({});
|
|
51
51
|
assert.deepEqual(actualStaticData, {});
|
|
52
52
|
});
|
|
53
|
-
|
|
54
|
-
it(
|
|
53
|
+
|
|
54
|
+
it("does not crash when theme attributes is null", function () {
|
|
55
55
|
const config = {
|
|
56
56
|
"publisher-settings": {
|
|
57
|
-
|
|
57
|
+
title: "abc",
|
|
58
58
|
},
|
|
59
59
|
"sketches-host": "abc.com",
|
|
60
60
|
"theme-attributes": null,
|
|
61
|
-
}
|
|
62
|
-
|
|
61
|
+
};
|
|
62
|
+
|
|
63
63
|
const expectedStaticData = {
|
|
64
64
|
"twitter:site": "abc",
|
|
65
65
|
"twitter:domain": "abc.com",
|
|
66
|
-
"og:site_name": "abc"
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const actualStaticData = generateStaticData(config)
|
|
70
|
-
assert.deepEqual(actualStaticData, expectedStaticData)
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it(
|
|
66
|
+
"og:site_name": "abc",
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const actualStaticData = generateStaticData(config);
|
|
70
|
+
assert.deepEqual(actualStaticData, expectedStaticData);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("fallback to publisher-name if title is empty", function () {
|
|
74
74
|
const config = {
|
|
75
75
|
"publisher-name": "Abc",
|
|
76
|
-
}
|
|
76
|
+
};
|
|
77
77
|
const expectedStaticData = {
|
|
78
78
|
"twitter:site": "Abc",
|
|
79
|
-
"og:site_name": "Abc"
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const actualStaticData = generateStaticData(config)
|
|
83
|
-
assert.deepEqual(actualStaticData, expectedStaticData)
|
|
84
|
-
})
|
|
85
|
-
})
|
|
79
|
+
"og:site_name": "Abc",
|
|
80
|
+
};
|
|
86
81
|
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
const actualStaticData = generateStaticData(config);
|
|
83
|
+
assert.deepEqual(actualStaticData, expectedStaticData);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe("Structured Data Generator", function () {
|
|
88
|
+
it("generates structured data", function () {
|
|
89
89
|
const config = {
|
|
90
90
|
"publisher-settings": {
|
|
91
|
-
|
|
91
|
+
title: "abc",
|
|
92
92
|
},
|
|
93
|
-
|
|
93
|
+
"publisher-name": "abc",
|
|
94
94
|
"sketches-host": "abc.com",
|
|
95
95
|
"theme-attributes": {
|
|
96
|
-
|
|
96
|
+
logo: "https://quintype.com/abc.png?w=300&h=300",
|
|
97
97
|
},
|
|
98
98
|
"social-links": {
|
|
99
99
|
"facebook-url": "https://www.facebook.com/abc/",
|
|
100
100
|
"google-plus-url": "",
|
|
101
101
|
"instagram-url": "https://www.instagram.com/abc",
|
|
102
|
-
"twitter-url": "https://twitter.com/abc"
|
|
102
|
+
"twitter-url": "https://twitter.com/abc",
|
|
103
103
|
},
|
|
104
|
-
"seo-metadata": [
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
"seo-metadata": [
|
|
105
|
+
{
|
|
106
|
+
"owner-type": "home",
|
|
107
|
+
data: {
|
|
108
|
+
"page-title": "Abc",
|
|
109
|
+
description: "News platform",
|
|
110
|
+
keywords: "abc,news,quintype",
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
],
|
|
112
114
|
};
|
|
113
115
|
const expectedStructuredData = {
|
|
114
116
|
organization: {
|
|
115
117
|
name: "abc",
|
|
116
118
|
url: "abc.com",
|
|
117
|
-
logo: {
|
|
118
|
-
|
|
119
|
+
logo: {
|
|
120
|
+
"@context": "http://schema.org",
|
|
121
|
+
"@type": "ImageObject",
|
|
122
|
+
author: "abc",
|
|
123
|
+
contentUrl: "https://quintype.com/abc.png?w=300&h=300",
|
|
124
|
+
url: "https://quintype.com/abc.png?w=300&h=300",
|
|
125
|
+
name: "logo",
|
|
126
|
+
width: "300",
|
|
127
|
+
height: "300",
|
|
128
|
+
},
|
|
129
|
+
sameAs: ["https://www.facebook.com/abc/", "", "https://www.instagram.com/abc", "https://twitter.com/abc"],
|
|
119
130
|
},
|
|
120
131
|
enableNewsArticle: false,
|
|
121
132
|
storyUrlAsMainEntityUrl: false,
|
|
@@ -127,45 +138,56 @@ describe('Seo Helpers', function() {
|
|
|
127
138
|
queryinput: "required name=query",
|
|
128
139
|
name: "Abc",
|
|
129
140
|
headline: "News platform",
|
|
130
|
-
keywords: "abc,news,quintype"
|
|
141
|
+
keywords: "abc,news,quintype",
|
|
131
142
|
},
|
|
132
143
|
};
|
|
133
|
-
const actualStructuredData = generateStructuredData(config)
|
|
134
|
-
assert.deepEqual(actualStructuredData, expectedStructuredData)
|
|
144
|
+
const actualStructuredData = generateStructuredData(config);
|
|
145
|
+
assert.deepEqual(actualStructuredData, expectedStructuredData);
|
|
135
146
|
});
|
|
136
147
|
|
|
137
|
-
it(
|
|
148
|
+
it("generate mainEntityStructured & NewsArticle data with theme-attributes", function () {
|
|
138
149
|
const config = {
|
|
139
150
|
"publisher-settings": {
|
|
140
|
-
|
|
151
|
+
title: "abc",
|
|
141
152
|
},
|
|
142
|
-
|
|
153
|
+
"publisher-name": "abc",
|
|
143
154
|
"sketches-host": "abc.com",
|
|
144
155
|
"theme-attributes": {
|
|
145
|
-
|
|
146
|
-
|
|
156
|
+
logo: "https://quintype.com/abc.png?w=300&h=300",
|
|
157
|
+
structured_data_news_article: true,
|
|
147
158
|
},
|
|
148
159
|
"social-links": {
|
|
149
160
|
"facebook-url": "https://www.facebook.com/abc/",
|
|
150
161
|
"google-plus-url": "",
|
|
151
162
|
"instagram-url": "https://www.instagram.com/abc",
|
|
152
|
-
"twitter-url": "https://twitter.com/abc"
|
|
163
|
+
"twitter-url": "https://twitter.com/abc",
|
|
153
164
|
},
|
|
154
|
-
"seo-metadata": [
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
165
|
+
"seo-metadata": [
|
|
166
|
+
{
|
|
167
|
+
"owner-type": "home",
|
|
168
|
+
data: {
|
|
169
|
+
"page-title": "Abc",
|
|
170
|
+
description: "News platform",
|
|
171
|
+
keywords: "abc,news,quintype",
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
],
|
|
162
175
|
};
|
|
163
176
|
const expectedStructuredData = {
|
|
164
177
|
organization: {
|
|
165
178
|
name: "abc",
|
|
166
179
|
url: "abc.com",
|
|
167
|
-
logo: {
|
|
168
|
-
|
|
180
|
+
logo: {
|
|
181
|
+
"@context": "http://schema.org",
|
|
182
|
+
"@type": "ImageObject",
|
|
183
|
+
author: "abc",
|
|
184
|
+
contentUrl: "https://quintype.com/abc.png?w=300&h=300",
|
|
185
|
+
url: "https://quintype.com/abc.png?w=300&h=300",
|
|
186
|
+
name: "logo",
|
|
187
|
+
width: "300",
|
|
188
|
+
height: "300",
|
|
189
|
+
},
|
|
190
|
+
sameAs: ["https://www.facebook.com/abc/", "", "https://www.instagram.com/abc", "https://twitter.com/abc"],
|
|
169
191
|
},
|
|
170
192
|
enableNewsArticle: true,
|
|
171
193
|
storyUrlAsMainEntityUrl: true,
|
|
@@ -177,46 +199,57 @@ describe('Seo Helpers', function() {
|
|
|
177
199
|
queryinput: "required name=query",
|
|
178
200
|
name: "Abc",
|
|
179
201
|
headline: "News platform",
|
|
180
|
-
keywords: "abc,news,quintype"
|
|
202
|
+
keywords: "abc,news,quintype",
|
|
181
203
|
},
|
|
182
204
|
};
|
|
183
|
-
const actualStructuredData = generateStructuredData(config)
|
|
184
|
-
assert.deepEqual(actualStructuredData, expectedStructuredData)
|
|
205
|
+
const actualStructuredData = generateStructuredData(config);
|
|
206
|
+
assert.deepEqual(actualStructuredData, expectedStructuredData);
|
|
185
207
|
});
|
|
186
|
-
|
|
187
|
-
it(
|
|
208
|
+
|
|
209
|
+
it("does not crash when the config is empty", function () {
|
|
188
210
|
const expectedStructuredData = {};
|
|
189
211
|
const actualStructuredData = generateStructuredData({});
|
|
190
212
|
assert.deepEqual(actualStructuredData, expectedStructuredData);
|
|
191
213
|
});
|
|
192
|
-
|
|
193
|
-
it(
|
|
214
|
+
|
|
215
|
+
it("does not crash when social links is null", function () {
|
|
194
216
|
const config = {
|
|
195
217
|
"publisher-settings": {
|
|
196
|
-
|
|
218
|
+
title: "abc",
|
|
197
219
|
},
|
|
198
220
|
"sketches-host": "abc.com",
|
|
199
221
|
"publisher-name": "Abc",
|
|
200
222
|
"theme-attributes": {
|
|
201
|
-
|
|
223
|
+
logo: "https://quintype.com/abc.png",
|
|
202
224
|
},
|
|
203
225
|
"social-links": null,
|
|
204
|
-
"seo-metadata": [
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
226
|
+
"seo-metadata": [
|
|
227
|
+
{
|
|
228
|
+
"owner-type": "home",
|
|
229
|
+
data: {
|
|
230
|
+
"page-title": "Abc",
|
|
231
|
+
description: "News platform",
|
|
232
|
+
keywords: "abc,news,quintype",
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
],
|
|
212
236
|
};
|
|
213
|
-
|
|
237
|
+
|
|
214
238
|
const expectedStructuredData = {
|
|
215
239
|
organization: {
|
|
216
240
|
name: "abc",
|
|
217
241
|
url: "abc.com",
|
|
218
|
-
logo: {
|
|
219
|
-
|
|
242
|
+
logo: {
|
|
243
|
+
"@context": "http://schema.org",
|
|
244
|
+
"@type": "ImageObject",
|
|
245
|
+
author: "Abc",
|
|
246
|
+
contentUrl: "https://quintype.com/abc.png",
|
|
247
|
+
url: "https://quintype.com/abc.png",
|
|
248
|
+
name: "logo",
|
|
249
|
+
width: "",
|
|
250
|
+
height: "",
|
|
251
|
+
},
|
|
252
|
+
sameAs: [],
|
|
220
253
|
},
|
|
221
254
|
storyUrlAsMainEntityUrl: false,
|
|
222
255
|
enableNewsArticle: false,
|
|
@@ -228,18 +261,18 @@ describe('Seo Helpers', function() {
|
|
|
228
261
|
queryinput: "required name=query",
|
|
229
262
|
name: "Abc",
|
|
230
263
|
headline: "News platform",
|
|
231
|
-
keywords: "abc,news,quintype"
|
|
264
|
+
keywords: "abc,news,quintype",
|
|
232
265
|
},
|
|
233
266
|
};
|
|
234
|
-
|
|
267
|
+
|
|
235
268
|
const actualStructuredData = generateStructuredData(config);
|
|
236
|
-
assert.deepEqual(actualStructuredData, expectedStructuredData)
|
|
269
|
+
assert.deepEqual(actualStructuredData, expectedStructuredData);
|
|
237
270
|
});
|
|
238
|
-
|
|
239
|
-
it(
|
|
271
|
+
|
|
272
|
+
it("does not crash when theme attributes is null", function () {
|
|
240
273
|
const config = {
|
|
241
274
|
"publisher-settings": {
|
|
242
|
-
|
|
275
|
+
title: "abc",
|
|
243
276
|
},
|
|
244
277
|
"sketches-host": "abc.com",
|
|
245
278
|
"publisher-name": "Abc",
|
|
@@ -248,19 +281,70 @@ describe('Seo Helpers', function() {
|
|
|
248
281
|
"facebook-url": "https://www.facebook.com/abc/",
|
|
249
282
|
"google-plus-url": "",
|
|
250
283
|
"instagram-url": "https://www.instagram.com/abc",
|
|
251
|
-
"twitter-url": "https://twitter.com/abc"
|
|
284
|
+
"twitter-url": "https://twitter.com/abc",
|
|
252
285
|
},
|
|
253
|
-
"seo-metadata": [
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
286
|
+
"seo-metadata": [
|
|
287
|
+
{
|
|
288
|
+
"owner-type": "home",
|
|
289
|
+
data: {
|
|
290
|
+
"page-title": "Abc",
|
|
291
|
+
description: "News platform",
|
|
292
|
+
keywords: "abc,news,quintype",
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
],
|
|
261
296
|
};
|
|
262
297
|
const actualStructuredData = generateStructuredData(config);
|
|
263
298
|
assert.deepEqual(actualStructuredData, {});
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it("takes the site twitter handle for twitter:site if present", function () {
|
|
302
|
+
const config = {
|
|
303
|
+
"publisher-settings": {
|
|
304
|
+
title: "abc",
|
|
305
|
+
},
|
|
306
|
+
"sketches-host": "abc.com",
|
|
307
|
+
"publisher-name": "Abc",
|
|
308
|
+
"theme-attributes": null,
|
|
309
|
+
"social-links": {
|
|
310
|
+
"twitter-url": "https://twitter.com/abc",
|
|
311
|
+
},
|
|
312
|
+
"seo-metadata": [
|
|
313
|
+
{
|
|
314
|
+
"owner-type": "home",
|
|
315
|
+
data: {
|
|
316
|
+
"page-title": "Abc",
|
|
317
|
+
description: "News platform",
|
|
318
|
+
keywords: "abc,news,quintype",
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
};
|
|
323
|
+
const actualStaticData = generateStaticData(config);
|
|
324
|
+
assert.strictEqual(actualStaticData["twitter:site"], "@abc");
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it("takes the title for twitter:site site twitter handle not present", function () {
|
|
328
|
+
const config = {
|
|
329
|
+
"publisher-settings": {
|
|
330
|
+
title: "this is the site title",
|
|
331
|
+
},
|
|
332
|
+
"sketches-host": "abc.com",
|
|
333
|
+
"publisher-name": "Abc",
|
|
334
|
+
"theme-attributes": null,
|
|
335
|
+
"seo-metadata": [
|
|
336
|
+
{
|
|
337
|
+
"owner-type": "home",
|
|
338
|
+
data: {
|
|
339
|
+
"page-title": "Abc",
|
|
340
|
+
description: "News platform",
|
|
341
|
+
keywords: "abc,news,quintype",
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
};
|
|
346
|
+
const actualStaticData = generateStaticData(config);
|
|
347
|
+
assert.strictEqual(actualStaticData["twitter:site"], "this is the site title");
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
});
|