wgt-node-utils 1.2.69 → 1.2.71
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/bundle.js +1 -1
- package/package.json +1 -1
- package/src/index.js +82 -48
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -879,10 +879,10 @@ class wgtNodeUtils {
|
|
|
879
879
|
* @param {string} applicationCategory: 应用分类 BrowserGame BrowserNews
|
|
880
880
|
* @param {string} genre: 游戏所属分类
|
|
881
881
|
*/
|
|
882
|
-
seoFun = ({ url, name, image, author, aggregateRating, description, hostname, languageList, lang, title, type, applicationCategory, genre,time }) => {
|
|
882
|
+
seoFun = ({ url, name, image, author, aggregateRating, description, hostname, languageList, lang, title, type, applicationCategory, genre, time, logo }) => {
|
|
883
883
|
const pathWithoutLang = url ? url.replace(/(https?:\/\/[^/]+)\/en\b/, "$1") : '/';
|
|
884
|
-
const seoRenderLdJson = this.renderLdJson({ pathWithoutLang, name, image, author, aggregateRating, description, hostname, type, languageList, applicationCategory, genre,time });
|
|
885
|
-
const seoRenderAlternateLink = this.renderAlternateLink({ languageList, url,
|
|
884
|
+
const seoRenderLdJson = this.renderLdJson({ pathWithoutLang, name, image, author, aggregateRating, description, hostname, type, languageList, applicationCategory, genre, time, logo });
|
|
885
|
+
const seoRenderAlternateLink = this.renderAlternateLink({ languageList, url, lang });
|
|
886
886
|
const seoraphAndTwitterFun = this.graphAndTwitterFun({ image, url, title, hostname, description, lang, pathWithoutLang });
|
|
887
887
|
const seoContent = {
|
|
888
888
|
seoRenderLdJson,
|
|
@@ -911,59 +911,71 @@ class wgtNodeUtils {
|
|
|
911
911
|
* @param applicationCategory: 应用分类 BrowserGame BrowserNews
|
|
912
912
|
* @param genre: 游戏所属分类
|
|
913
913
|
*/
|
|
914
|
-
renderLdJson = ({
|
|
915
|
-
const currentType = type || '
|
|
914
|
+
renderLdJson = ({ pathWithoutLang, name, image, author, aggregateRating, description, hostname, type, languageList, applicationCategory, genre, time, logo }) => {
|
|
915
|
+
const currentType = type || 'WebPage';
|
|
916
916
|
const inLanguage = languageList ? languageList.map(item => item.code) : [];
|
|
917
917
|
const organizationUrl = `https://${hostname}`;
|
|
918
|
-
|
|
919
|
-
const
|
|
918
|
+
const siteName = author || hostname;
|
|
919
|
+
const siteLogo = logo;
|
|
920
|
+
let ld = {
|
|
920
921
|
'@context': 'https://schema.org/',
|
|
921
|
-
'@type': currentType,
|
|
922
|
+
'@type': currentType, // 默认为更通用的 WebPage
|
|
922
923
|
'name': name,
|
|
923
924
|
'description': description,
|
|
924
|
-
'url':
|
|
925
|
+
'url': pathWithoutLang,
|
|
925
926
|
'image': image,
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
'
|
|
932
|
-
|
|
933
|
-
'
|
|
934
|
-
'url':
|
|
927
|
+
|
|
928
|
+
};
|
|
929
|
+
const orgStructure = {
|
|
930
|
+
'@type': 'Organization',
|
|
931
|
+
'name': siteName,
|
|
932
|
+
'url': organizationUrl,
|
|
933
|
+
'logo': {
|
|
934
|
+
'@type': 'ImageObject',
|
|
935
|
+
'url': siteLogo
|
|
935
936
|
}
|
|
936
937
|
};
|
|
937
|
-
|
|
938
|
+
const potentialAction = {
|
|
939
|
+
"@type": "SearchAction",
|
|
940
|
+
"target": `${organizationUrl}/search/{search_term_string}`,
|
|
941
|
+
"query-input": "required name=search_term_string"
|
|
942
|
+
}
|
|
938
943
|
if (inLanguage.length > 0) {
|
|
939
944
|
ld.inLanguage = inLanguage.length === 1 ? inLanguage[0] : inLanguage;
|
|
940
945
|
}
|
|
941
946
|
|
|
942
|
-
if (
|
|
943
|
-
ld.headline = name
|
|
947
|
+
if (type === 'NewsArticle') {
|
|
948
|
+
ld.headline = name?.substring(0, 110);
|
|
944
949
|
ld.datePublished = time || new Date().toISOString();
|
|
945
|
-
ld.
|
|
946
|
-
'@type': '
|
|
947
|
-
'
|
|
950
|
+
ld.author = {
|
|
951
|
+
'@type': 'Person', // 新闻建议用 Person,或者具体的编辑名
|
|
952
|
+
'name': siteName,
|
|
953
|
+
'url': organizationUrl
|
|
948
954
|
};
|
|
949
|
-
|
|
955
|
+
ld.publisher = orgStructure;
|
|
956
|
+
ld.mainEntityOfPage = { '@type': 'WebPage', '@id': pathWithoutLang };
|
|
957
|
+
if (genre) ld.genre = genre;
|
|
958
|
+
|
|
959
|
+
} else if (type.includes("VideoGame") || type.includes("WebApplication")) {
|
|
950
960
|
ld.operatingSystem = 'Web Browser';
|
|
951
961
|
ld.applicationCategory = applicationCategory || 'BrowserGame';
|
|
952
962
|
ld.offers = {
|
|
953
963
|
'@type': 'Offer',
|
|
954
964
|
'price': '0',
|
|
955
|
-
'priceCurrency': 'USD'
|
|
956
|
-
'availability': 'https://schema.org/InStock',
|
|
957
|
-
'url': url
|
|
965
|
+
'priceCurrency': 'USD'
|
|
958
966
|
};
|
|
959
|
-
|
|
960
|
-
if (aggregateRating
|
|
961
|
-
ld.aggregateRating =
|
|
967
|
+
// 修复 reviewCount 报错:必须有值且大于 0 才渲染
|
|
968
|
+
if (aggregateRating?.reviewCount > 0 && aggregateRating?.ratingValue > 0) {
|
|
969
|
+
ld.aggregateRating = {
|
|
970
|
+
'@type': 'AggregateRating',
|
|
971
|
+
'ratingValue': aggregateRating.ratingValue,
|
|
972
|
+
'reviewCount': aggregateRating.reviewCount
|
|
973
|
+
};
|
|
962
974
|
}
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
ld.
|
|
975
|
+
} else {
|
|
976
|
+
ld['@type'] = 'WebSite';
|
|
977
|
+
ld.publisher = orgStructure;
|
|
978
|
+
ld.potentialAction = potentialAction;
|
|
967
979
|
}
|
|
968
980
|
|
|
969
981
|
return ld;
|
|
@@ -975,20 +987,42 @@ class wgtNodeUtils {
|
|
|
975
987
|
* @param {Array} languageList - 语言列表
|
|
976
988
|
* @param {string} url - 页面URL
|
|
977
989
|
*/
|
|
978
|
-
renderAlternateLink = ({ languageList, url,
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
|
|
990
|
+
renderAlternateLink = ({ languageList, url, lang }) => {
|
|
991
|
+
// 提取所有语言 code
|
|
992
|
+
const languageCodes = languageList.map(item => item.code).join('|');
|
|
993
|
+
const langRegex = new RegExp(`^/(${languageCodes})(?=/|$)`);
|
|
994
|
+
|
|
995
|
+
// 提取域名和路径
|
|
996
|
+
const originMatch = url.match(/^(https?:\/\/[^/]+)(.*)$/);
|
|
997
|
+
const origin = originMatch ? originMatch[1] : '';
|
|
998
|
+
const pathname = originMatch ? originMatch[2] : '/';
|
|
999
|
+
|
|
1000
|
+
// 去掉已有语言前缀
|
|
1001
|
+
const cleanPath = pathname.replace(langRegex, '') || '/';
|
|
1002
|
+
|
|
1003
|
+
// 构建不同语言的链接
|
|
1004
|
+
const languageLinkList = languageList.map(item => {
|
|
1005
|
+
const href = item.code === 'en'
|
|
1006
|
+
? `${origin}${cleanPath}` // 英文不加前缀
|
|
1007
|
+
: `${origin}/${item.code}${cleanPath === '/' ? '' : cleanPath}`; // 其他语言加前缀
|
|
1008
|
+
return {
|
|
1009
|
+
rel: 'alternate',
|
|
1010
|
+
hrefLang: item.code,
|
|
1011
|
+
href
|
|
1012
|
+
};
|
|
1013
|
+
});
|
|
1014
|
+
|
|
1015
|
+
// x-default 指向英文(默认路径)
|
|
1016
|
+
languageLinkList.push({ rel: 'alternate', hrefLang: 'x-default', href: `${origin}${cleanPath}` });
|
|
1017
|
+
|
|
1018
|
+
// canonical 指向当前语言的 URL
|
|
1019
|
+
const canonicalUrl = lang && lang !== 'en'
|
|
1020
|
+
? `${origin}/${lang}${cleanPath === '/' ? '' : cleanPath}`
|
|
1021
|
+
: `${origin}${cleanPath}`;
|
|
989
1022
|
languageLinkList.push({ rel: 'canonical', href: canonicalUrl });
|
|
990
|
-
|
|
991
|
-
|
|
1023
|
+
|
|
1024
|
+
return languageLinkList;
|
|
1025
|
+
};
|
|
992
1026
|
// Open Graph 和 Twitter Card 站外引流触点
|
|
993
1027
|
graphAndTwitterFun = ({ image, title, hostname, description, lang, pathWithoutLang }) => {
|
|
994
1028
|
|