@masters-ws/react-seo 1.2.1 → 1.4.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/README.md +1354 -97
- package/dist/chunk-6RBCF5I5.mjs +567 -0
- package/dist/chunk-FFE2ZOOC.mjs +945 -0
- package/dist/chunk-L6YRMB7H.mjs +988 -0
- package/dist/chunk-UBBPNSEV.mjs +1016 -0
- package/dist/core/index.d.mts +2 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.js +684 -40
- package/dist/core/index.mjs +29 -3
- package/dist/index-CkB-Wt4c.d.mts +1272 -0
- package/dist/index-CkB-Wt4c.d.ts +1272 -0
- package/dist/index-DEE7ZyDx.d.mts +1193 -0
- package/dist/index-DEE7ZyDx.d.ts +1193 -0
- package/dist/index-Wu9j5oCk.d.mts +721 -0
- package/dist/index-Wu9j5oCk.d.ts +721 -0
- package/dist/index.d.mts +13 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.js +1771 -144
- package/dist/index.mjs +1030 -32
- package/package.json +2 -8
package/dist/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name in all)
|
|
8
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -15,12 +20,172 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
20
|
}
|
|
16
21
|
return to;
|
|
17
22
|
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
18
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
32
|
|
|
33
|
+
// node_modules/react-fast-compare/index.js
|
|
34
|
+
var require_react_fast_compare = __commonJS({
|
|
35
|
+
"node_modules/react-fast-compare/index.js"(exports2, module2) {
|
|
36
|
+
"use strict";
|
|
37
|
+
var hasElementType = typeof Element !== "undefined";
|
|
38
|
+
var hasMap = typeof Map === "function";
|
|
39
|
+
var hasSet = typeof Set === "function";
|
|
40
|
+
var hasArrayBuffer = typeof ArrayBuffer === "function" && !!ArrayBuffer.isView;
|
|
41
|
+
function equal(a, b) {
|
|
42
|
+
if (a === b) return true;
|
|
43
|
+
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
44
|
+
if (a.constructor !== b.constructor) return false;
|
|
45
|
+
var length, i, keys;
|
|
46
|
+
if (Array.isArray(a)) {
|
|
47
|
+
length = a.length;
|
|
48
|
+
if (length != b.length) return false;
|
|
49
|
+
for (i = length; i-- !== 0; )
|
|
50
|
+
if (!equal(a[i], b[i])) return false;
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
var it;
|
|
54
|
+
if (hasMap && a instanceof Map && b instanceof Map) {
|
|
55
|
+
if (a.size !== b.size) return false;
|
|
56
|
+
it = a.entries();
|
|
57
|
+
while (!(i = it.next()).done)
|
|
58
|
+
if (!b.has(i.value[0])) return false;
|
|
59
|
+
it = a.entries();
|
|
60
|
+
while (!(i = it.next()).done)
|
|
61
|
+
if (!equal(i.value[1], b.get(i.value[0]))) return false;
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
if (hasSet && a instanceof Set && b instanceof Set) {
|
|
65
|
+
if (a.size !== b.size) return false;
|
|
66
|
+
it = a.entries();
|
|
67
|
+
while (!(i = it.next()).done)
|
|
68
|
+
if (!b.has(i.value[0])) return false;
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
if (hasArrayBuffer && ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
|
|
72
|
+
length = a.length;
|
|
73
|
+
if (length != b.length) return false;
|
|
74
|
+
for (i = length; i-- !== 0; )
|
|
75
|
+
if (a[i] !== b[i]) return false;
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
|
|
79
|
+
if (a.valueOf !== Object.prototype.valueOf && typeof a.valueOf === "function" && typeof b.valueOf === "function") return a.valueOf() === b.valueOf();
|
|
80
|
+
if (a.toString !== Object.prototype.toString && typeof a.toString === "function" && typeof b.toString === "function") return a.toString() === b.toString();
|
|
81
|
+
keys = Object.keys(a);
|
|
82
|
+
length = keys.length;
|
|
83
|
+
if (length !== Object.keys(b).length) return false;
|
|
84
|
+
for (i = length; i-- !== 0; )
|
|
85
|
+
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
|
|
86
|
+
if (hasElementType && a instanceof Element) return false;
|
|
87
|
+
for (i = length; i-- !== 0; ) {
|
|
88
|
+
if ((keys[i] === "_owner" || keys[i] === "__v" || keys[i] === "__o") && a.$$typeof) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (!equal(a[keys[i]], b[keys[i]])) return false;
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
return a !== a && b !== b;
|
|
96
|
+
}
|
|
97
|
+
module2.exports = function isEqual(a, b) {
|
|
98
|
+
try {
|
|
99
|
+
return equal(a, b);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if ((error.message || "").match(/stack|recursion/i)) {
|
|
102
|
+
console.warn("react-fast-compare cannot handle circular refs");
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// node_modules/invariant/invariant.js
|
|
112
|
+
var require_invariant = __commonJS({
|
|
113
|
+
"node_modules/invariant/invariant.js"(exports2, module2) {
|
|
114
|
+
"use strict";
|
|
115
|
+
var NODE_ENV = process.env.NODE_ENV;
|
|
116
|
+
var invariant2 = function(condition, format, a, b, c, d, e, f) {
|
|
117
|
+
if (NODE_ENV !== "production") {
|
|
118
|
+
if (format === void 0) {
|
|
119
|
+
throw new Error("invariant requires an error message argument");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (!condition) {
|
|
123
|
+
var error;
|
|
124
|
+
if (format === void 0) {
|
|
125
|
+
error = new Error(
|
|
126
|
+
"Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings."
|
|
127
|
+
);
|
|
128
|
+
} else {
|
|
129
|
+
var args = [a, b, c, d, e, f];
|
|
130
|
+
var argIndex = 0;
|
|
131
|
+
error = new Error(
|
|
132
|
+
format.replace(/%s/g, function() {
|
|
133
|
+
return args[argIndex++];
|
|
134
|
+
})
|
|
135
|
+
);
|
|
136
|
+
error.name = "Invariant Violation";
|
|
137
|
+
}
|
|
138
|
+
error.framesToPop = 1;
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
module2.exports = invariant2;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// node_modules/shallowequal/index.js
|
|
147
|
+
var require_shallowequal = __commonJS({
|
|
148
|
+
"node_modules/shallowequal/index.js"(exports2, module2) {
|
|
149
|
+
"use strict";
|
|
150
|
+
module2.exports = function shallowEqual2(objA, objB, compare, compareContext) {
|
|
151
|
+
var ret = compare ? compare.call(compareContext, objA, objB) : void 0;
|
|
152
|
+
if (ret !== void 0) {
|
|
153
|
+
return !!ret;
|
|
154
|
+
}
|
|
155
|
+
if (objA === objB) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
if (typeof objA !== "object" || !objA || typeof objB !== "object" || !objB) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
var keysA = Object.keys(objA);
|
|
162
|
+
var keysB = Object.keys(objB);
|
|
163
|
+
if (keysA.length !== keysB.length) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);
|
|
167
|
+
for (var idx = 0; idx < keysA.length; idx++) {
|
|
168
|
+
var key = keysA[idx];
|
|
169
|
+
if (!bHasOwnProperty(key)) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
var valueA = objA[key];
|
|
173
|
+
var valueB = objB[key];
|
|
174
|
+
ret = compare ? compare.call(compareContext, valueA, valueB, key) : void 0;
|
|
175
|
+
if (ret === false || ret === void 0 && valueA !== valueB) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
20
184
|
// src/index.ts
|
|
21
185
|
var index_exports = {};
|
|
22
186
|
__export(index_exports, {
|
|
23
187
|
Breadcrumb: () => Breadcrumb,
|
|
188
|
+
JsonLd: () => JsonLd,
|
|
24
189
|
SEO: () => SEO,
|
|
25
190
|
SEOProvider: () => SEOProvider,
|
|
26
191
|
SeoArticle: () => SeoArticle,
|
|
@@ -37,11 +202,19 @@ __export(index_exports, {
|
|
|
37
202
|
SeoReview: () => SeoReview,
|
|
38
203
|
SeoTag: () => SeoTag,
|
|
39
204
|
SeoVideo: () => SeoVideo,
|
|
205
|
+
cleanSchema: () => cleanSchema,
|
|
206
|
+
generateArticleMetadata: () => generateArticleMetadata,
|
|
40
207
|
generateArticleSchema: () => generateArticleSchema,
|
|
41
208
|
generateBookSchema: () => generateBookSchema,
|
|
42
209
|
generateBreadcrumbSchema: () => generateBreadcrumbSchema,
|
|
210
|
+
generateCategoryMetadata: () => generateCategoryMetadata,
|
|
211
|
+
generateCollectionPageSchema: () => generateCollectionPageSchema,
|
|
43
212
|
generateEventSchema: () => generateEventSchema,
|
|
44
213
|
generateFAQSchema: () => generateFAQSchema,
|
|
214
|
+
generateHomepageMetadata: () => generateHomepageMetadata,
|
|
215
|
+
generateHowToSchema: () => generateHowToSchema,
|
|
216
|
+
generateItemListSchema: () => generateItemListSchema,
|
|
217
|
+
generateJobPostingSchema: () => generateJobPostingSchema,
|
|
45
218
|
generateLocalBusinessSchema: () => generateLocalBusinessSchema,
|
|
46
219
|
generateMovieSchema: () => generateMovieSchema,
|
|
47
220
|
generateOrganizationSchema: () => generateOrganizationSchema,
|
|
@@ -49,83 +222,267 @@ __export(index_exports, {
|
|
|
49
222
|
generatePaginationLinks: () => generatePaginationLinks,
|
|
50
223
|
generatePodcastEpisodeSchema: () => generatePodcastEpisodeSchema,
|
|
51
224
|
generatePodcastSchema: () => generatePodcastSchema,
|
|
225
|
+
generateProductMetadata: () => generateProductMetadata,
|
|
52
226
|
generateProductSchema: () => generateProductSchema,
|
|
227
|
+
generateRecipeSchema: () => generateRecipeSchema,
|
|
53
228
|
generateSoftwareSchema: () => generateSoftwareSchema,
|
|
54
229
|
generateVideoSchema: () => generateVideoSchema,
|
|
230
|
+
generateWebPageSchema: () => generateWebPageSchema,
|
|
55
231
|
generateWebSiteSchema: () => generateWebSiteSchema,
|
|
56
232
|
toNextMetadata: () => toNextMetadata,
|
|
57
|
-
useSEOConfig: () => useSEOConfig
|
|
233
|
+
useSEOConfig: () => useSEOConfig,
|
|
234
|
+
validateSEO: () => validateSEO
|
|
58
235
|
});
|
|
59
236
|
module.exports = __toCommonJS(index_exports);
|
|
60
237
|
|
|
238
|
+
// src/core/utils.ts
|
|
239
|
+
function cleanSchema(obj) {
|
|
240
|
+
if (Array.isArray(obj)) {
|
|
241
|
+
return obj.filter((item) => item !== void 0 && item !== null).map((item) => typeof item === "object" ? cleanSchema(item) : item);
|
|
242
|
+
}
|
|
243
|
+
const cleaned = {};
|
|
244
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
245
|
+
if (value === void 0 || value === null) continue;
|
|
246
|
+
if (Array.isArray(value)) {
|
|
247
|
+
const cleanedArr = value.filter((item) => item !== void 0 && item !== null).map((item) => typeof item === "object" && item !== null ? cleanSchema(item) : item);
|
|
248
|
+
if (cleanedArr.length > 0) {
|
|
249
|
+
cleaned[key] = cleanedArr;
|
|
250
|
+
}
|
|
251
|
+
} else if (typeof value === "object") {
|
|
252
|
+
cleaned[key] = cleanSchema(value);
|
|
253
|
+
} else {
|
|
254
|
+
cleaned[key] = value;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return cleaned;
|
|
258
|
+
}
|
|
259
|
+
function validateSEO(schemaType, data, requiredFields) {
|
|
260
|
+
const warnings = [];
|
|
261
|
+
for (const field of requiredFields) {
|
|
262
|
+
const value = data[field];
|
|
263
|
+
if (value === void 0 || value === null || value === "") {
|
|
264
|
+
warnings.push(`[react-seo] Warning: "${field}" is missing in ${schemaType} schema. Google may not show rich results.`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (warnings.length > 0 && typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV !== "production") {
|
|
268
|
+
warnings.forEach((w) => console.warn(w));
|
|
269
|
+
}
|
|
270
|
+
return warnings;
|
|
271
|
+
}
|
|
272
|
+
|
|
61
273
|
// src/core/schemas.ts
|
|
62
274
|
function generateOrganizationSchema(config) {
|
|
63
|
-
return {
|
|
275
|
+
return cleanSchema({
|
|
64
276
|
"@context": "https://schema.org",
|
|
65
277
|
"@type": "Organization",
|
|
66
278
|
"name": config.name,
|
|
67
279
|
"url": config.url,
|
|
68
280
|
"logo": config.logo,
|
|
281
|
+
"description": config.description,
|
|
69
282
|
"sameAs": config.socialLinks || []
|
|
70
|
-
};
|
|
283
|
+
});
|
|
71
284
|
}
|
|
72
285
|
function generateWebSiteSchema(config) {
|
|
73
|
-
return {
|
|
286
|
+
return cleanSchema({
|
|
74
287
|
"@context": "https://schema.org",
|
|
75
288
|
"@type": "WebSite",
|
|
76
289
|
"name": config.name,
|
|
77
290
|
"url": config.url,
|
|
291
|
+
"description": config.description,
|
|
292
|
+
"publisher": {
|
|
293
|
+
"@type": "Organization",
|
|
294
|
+
"name": config.name,
|
|
295
|
+
"logo": config.logo
|
|
296
|
+
},
|
|
78
297
|
"potentialAction": {
|
|
79
298
|
"@type": "SearchAction",
|
|
80
299
|
"target": `${config.url}/search?q={search_term_string}`,
|
|
81
300
|
"query-input": "required name=search_term_string"
|
|
82
301
|
}
|
|
83
|
-
};
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
function generateWebPageSchema(data, config) {
|
|
305
|
+
return cleanSchema({
|
|
306
|
+
"@context": "https://schema.org",
|
|
307
|
+
"@type": "WebPage",
|
|
308
|
+
"name": data.name,
|
|
309
|
+
"description": data.description,
|
|
310
|
+
"url": data.url,
|
|
311
|
+
"image": data.image,
|
|
312
|
+
"datePublished": data.datePublished,
|
|
313
|
+
"dateModified": data.dateModified,
|
|
314
|
+
"isPartOf": {
|
|
315
|
+
"@type": "WebSite",
|
|
316
|
+
"name": config.name,
|
|
317
|
+
"url": config.url
|
|
318
|
+
},
|
|
319
|
+
"breadcrumb": data.breadcrumb ? generateBreadcrumbSchema(data.breadcrumb) : void 0
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
function generateCollectionPageSchema(data, config) {
|
|
323
|
+
return cleanSchema({
|
|
324
|
+
"@context": "https://schema.org",
|
|
325
|
+
"@type": "CollectionPage",
|
|
326
|
+
"name": data.name,
|
|
327
|
+
"description": data.description,
|
|
328
|
+
"url": data.url,
|
|
329
|
+
"image": data.image,
|
|
330
|
+
"numberOfItems": data.numberOfItems,
|
|
331
|
+
"isPartOf": {
|
|
332
|
+
"@type": "WebSite",
|
|
333
|
+
"name": config.name,
|
|
334
|
+
"url": config.url
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
function generateItemListSchema(data) {
|
|
339
|
+
return cleanSchema({
|
|
340
|
+
"@context": "https://schema.org",
|
|
341
|
+
"@type": "ItemList",
|
|
342
|
+
"name": data.name,
|
|
343
|
+
"url": data.url,
|
|
344
|
+
"itemListOrder": data.itemListOrder === "ascending" ? "https://schema.org/ItemListOrderAscending" : data.itemListOrder === "descending" ? "https://schema.org/ItemListOrderDescending" : "https://schema.org/ItemListUnordered",
|
|
345
|
+
"numberOfItems": data.items.length,
|
|
346
|
+
"itemListElement": data.items.map((item, index) => ({
|
|
347
|
+
"@type": "ListItem",
|
|
348
|
+
"position": item.position || index + 1,
|
|
349
|
+
"name": item.name,
|
|
350
|
+
"url": item.url,
|
|
351
|
+
"image": item.image
|
|
352
|
+
}))
|
|
353
|
+
});
|
|
84
354
|
}
|
|
85
355
|
function generateArticleSchema(data, config) {
|
|
356
|
+
validateSEO("NewsArticle", data, ["title", "description", "image", "publishedTime", "author"]);
|
|
86
357
|
const org = generateOrganizationSchema(config);
|
|
87
|
-
return {
|
|
358
|
+
return cleanSchema({
|
|
88
359
|
"@context": "https://schema.org",
|
|
89
360
|
"@type": "NewsArticle",
|
|
90
361
|
"headline": data.title,
|
|
91
362
|
"description": data.description,
|
|
92
|
-
"image": data.image
|
|
363
|
+
"image": data.image,
|
|
93
364
|
"datePublished": data.publishedTime,
|
|
94
365
|
"dateModified": data.modifiedTime || data.publishedTime,
|
|
95
366
|
"mainEntityOfPage": data.url,
|
|
367
|
+
"wordCount": data.wordCount,
|
|
96
368
|
"author": data.author ? {
|
|
97
369
|
"@type": "Person",
|
|
98
370
|
"name": data.author.name,
|
|
99
371
|
"url": data.author.url
|
|
100
372
|
} : org,
|
|
101
373
|
"publisher": org
|
|
102
|
-
};
|
|
374
|
+
});
|
|
103
375
|
}
|
|
104
376
|
function generateProductSchema(data) {
|
|
105
|
-
|
|
377
|
+
validateSEO("Product", data, ["name", "description", "image", "price"]);
|
|
378
|
+
let offers;
|
|
379
|
+
if (data.variants && data.variants.length > 0) {
|
|
380
|
+
const prices = data.variants.map((v) => v.price);
|
|
381
|
+
offers = {
|
|
382
|
+
"@type": "AggregateOffer",
|
|
383
|
+
"lowPrice": Math.min(...prices),
|
|
384
|
+
"highPrice": Math.max(...prices),
|
|
385
|
+
"priceCurrency": data.currency || data.variants[0]?.currency || "USD",
|
|
386
|
+
"offerCount": data.variants.length,
|
|
387
|
+
"offers": data.variants.map((v) => cleanSchema({
|
|
388
|
+
"@type": "Offer",
|
|
389
|
+
"name": v.name,
|
|
390
|
+
"sku": v.sku,
|
|
391
|
+
"price": v.price,
|
|
392
|
+
"priceCurrency": v.currency || data.currency || "USD",
|
|
393
|
+
"availability": v.availability || data.availability || "https://schema.org/InStock",
|
|
394
|
+
"url": v.url || data.url,
|
|
395
|
+
"image": v.image,
|
|
396
|
+
"itemCondition": data.condition ? `https://schema.org/${data.condition}` : void 0
|
|
397
|
+
}))
|
|
398
|
+
};
|
|
399
|
+
} else {
|
|
400
|
+
offers = cleanSchema({
|
|
401
|
+
"@type": "Offer",
|
|
402
|
+
"url": data.url,
|
|
403
|
+
"priceCurrency": data.currency || "USD",
|
|
404
|
+
"price": data.price,
|
|
405
|
+
"availability": data.availability || "https://schema.org/InStock",
|
|
406
|
+
"itemCondition": data.condition ? `https://schema.org/${data.condition}` : void 0,
|
|
407
|
+
"seller": data.seller ? {
|
|
408
|
+
"@type": "Organization",
|
|
409
|
+
"name": data.seller.name,
|
|
410
|
+
"url": data.seller.url
|
|
411
|
+
} : void 0,
|
|
412
|
+
"hasMerchantReturnPolicy": data.returnPolicy ? cleanSchema({
|
|
413
|
+
"@type": "MerchantReturnPolicy",
|
|
414
|
+
"applicableCountry": data.shipping?.shippingDestination,
|
|
415
|
+
"returnPolicyCategory": data.returnPolicy.returnPolicyCategory ? `https://schema.org/${data.returnPolicy.returnPolicyCategory}` : "https://schema.org/MerchantReturnFiniteReturnWindow",
|
|
416
|
+
"merchantReturnDays": data.returnPolicy.returnWithin,
|
|
417
|
+
"returnMethod": data.returnPolicy.returnMethod ? `https://schema.org/${data.returnPolicy.returnMethod}` : void 0,
|
|
418
|
+
"returnFees": data.returnPolicy.returnFees ? `https://schema.org/${data.returnPolicy.returnFees}` : void 0
|
|
419
|
+
}) : void 0,
|
|
420
|
+
"shippingDetails": data.shipping ? cleanSchema({
|
|
421
|
+
"@type": "OfferShippingDetails",
|
|
422
|
+
"shippingRate": data.shipping.shippingRate ? {
|
|
423
|
+
"@type": "MonetaryAmount",
|
|
424
|
+
"value": data.shipping.shippingRate.value,
|
|
425
|
+
"currency": data.shipping.shippingRate.currency
|
|
426
|
+
} : void 0,
|
|
427
|
+
"shippingDestination": data.shipping.shippingDestination ? {
|
|
428
|
+
"@type": "DefinedRegion",
|
|
429
|
+
"addressCountry": data.shipping.shippingDestination
|
|
430
|
+
} : void 0,
|
|
431
|
+
"deliveryTime": data.shipping.deliveryTime ? {
|
|
432
|
+
"@type": "ShippingDeliveryTime",
|
|
433
|
+
"handlingTime": {
|
|
434
|
+
"@type": "QuantitativeValue",
|
|
435
|
+
"minValue": 0,
|
|
436
|
+
"maxValue": 1,
|
|
437
|
+
"unitCode": "DAY"
|
|
438
|
+
},
|
|
439
|
+
"transitTime": {
|
|
440
|
+
"@type": "QuantitativeValue",
|
|
441
|
+
"minValue": data.shipping.deliveryTime.minDays,
|
|
442
|
+
"maxValue": data.shipping.deliveryTime.maxDays,
|
|
443
|
+
"unitCode": "DAY"
|
|
444
|
+
}
|
|
445
|
+
} : void 0,
|
|
446
|
+
"freeShippingThreshold": data.shipping.freeShippingThreshold ? {
|
|
447
|
+
"@type": "MonetaryAmount",
|
|
448
|
+
"value": data.shipping.freeShippingThreshold,
|
|
449
|
+
"currency": data.shipping.shippingRate?.currency || data.currency || "USD"
|
|
450
|
+
} : void 0
|
|
451
|
+
}) : void 0
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
const reviewList = data.reviews?.map((r) => cleanSchema({
|
|
455
|
+
"@type": "Review",
|
|
456
|
+
"author": { "@type": "Person", "name": r.author },
|
|
457
|
+
"datePublished": r.datePublished,
|
|
458
|
+
"reviewBody": r.reviewBody,
|
|
459
|
+
"reviewRating": {
|
|
460
|
+
"@type": "Rating",
|
|
461
|
+
"ratingValue": r.ratingValue,
|
|
462
|
+
"bestRating": r.bestRating || 5
|
|
463
|
+
}
|
|
464
|
+
}));
|
|
465
|
+
return cleanSchema({
|
|
106
466
|
"@context": "https://schema.org",
|
|
107
467
|
"@type": "Product",
|
|
108
468
|
"name": data.name,
|
|
109
469
|
"description": data.description,
|
|
110
470
|
"image": data.image,
|
|
111
471
|
"sku": data.sku,
|
|
472
|
+
"gtin": data.gtin,
|
|
473
|
+
"mpn": data.mpn,
|
|
112
474
|
"brand": data.brand ? { "@type": "Brand", "name": data.brand } : void 0,
|
|
113
|
-
"offers":
|
|
114
|
-
"@type": "Offer",
|
|
115
|
-
"url": data.url,
|
|
116
|
-
"priceCurrency": data.currency || "USD",
|
|
117
|
-
"price": data.price,
|
|
118
|
-
"availability": data.availability || "https://schema.org/InStock"
|
|
119
|
-
},
|
|
475
|
+
"offers": offers,
|
|
120
476
|
"aggregateRating": data.rating ? {
|
|
121
477
|
"@type": "AggregateRating",
|
|
122
478
|
"ratingValue": data.rating,
|
|
123
479
|
"reviewCount": data.reviewCount || 1
|
|
124
|
-
} : void 0
|
|
125
|
-
|
|
480
|
+
} : void 0,
|
|
481
|
+
"review": reviewList && reviewList.length > 0 ? reviewList : void 0
|
|
482
|
+
});
|
|
126
483
|
}
|
|
127
484
|
function generateFAQSchema(questions) {
|
|
128
|
-
return {
|
|
485
|
+
return cleanSchema({
|
|
129
486
|
"@context": "https://schema.org",
|
|
130
487
|
"@type": "FAQPage",
|
|
131
488
|
"mainEntity": questions.map((item) => ({
|
|
@@ -136,10 +493,10 @@ function generateFAQSchema(questions) {
|
|
|
136
493
|
"text": item.a
|
|
137
494
|
}
|
|
138
495
|
}))
|
|
139
|
-
};
|
|
496
|
+
});
|
|
140
497
|
}
|
|
141
498
|
function generateBreadcrumbSchema(items) {
|
|
142
|
-
return {
|
|
499
|
+
return cleanSchema({
|
|
143
500
|
"@context": "https://schema.org",
|
|
144
501
|
"@type": "BreadcrumbList",
|
|
145
502
|
"itemListElement": items.map((item, index) => ({
|
|
@@ -148,10 +505,11 @@ function generateBreadcrumbSchema(items) {
|
|
|
148
505
|
"name": item.name,
|
|
149
506
|
"item": item.item
|
|
150
507
|
}))
|
|
151
|
-
};
|
|
508
|
+
});
|
|
152
509
|
}
|
|
153
510
|
function generateVideoSchema(data) {
|
|
154
|
-
|
|
511
|
+
validateSEO("VideoObject", data, ["name", "description", "thumbnailUrl", "uploadDate"]);
|
|
512
|
+
return cleanSchema({
|
|
155
513
|
"@context": "https://schema.org",
|
|
156
514
|
"@type": "VideoObject",
|
|
157
515
|
"name": data.name,
|
|
@@ -161,11 +519,11 @@ function generateVideoSchema(data) {
|
|
|
161
519
|
"duration": data.duration,
|
|
162
520
|
"contentUrl": data.contentUrl,
|
|
163
521
|
"embedUrl": data.embedUrl
|
|
164
|
-
};
|
|
522
|
+
});
|
|
165
523
|
}
|
|
166
524
|
function generateEventSchema(data) {
|
|
167
525
|
const isOnline = data.location && "url" in data.location;
|
|
168
|
-
return {
|
|
526
|
+
return cleanSchema({
|
|
169
527
|
"@context": "https://schema.org",
|
|
170
528
|
"@type": "Event",
|
|
171
529
|
"name": data.name,
|
|
@@ -188,10 +546,10 @@ function generateEventSchema(data) {
|
|
|
188
546
|
"priceCurrency": data.offers.currency,
|
|
189
547
|
"url": data.offers.url
|
|
190
548
|
} : void 0
|
|
191
|
-
};
|
|
549
|
+
});
|
|
192
550
|
}
|
|
193
551
|
function generateLocalBusinessSchema(data) {
|
|
194
|
-
return {
|
|
552
|
+
return cleanSchema({
|
|
195
553
|
"@context": "https://schema.org",
|
|
196
554
|
"@type": "LocalBusiness",
|
|
197
555
|
"name": data.name,
|
|
@@ -213,10 +571,10 @@ function generateLocalBusinessSchema(data) {
|
|
|
213
571
|
} : void 0,
|
|
214
572
|
"openingHours": data.openingHours,
|
|
215
573
|
"priceRange": data.priceRange
|
|
216
|
-
};
|
|
574
|
+
});
|
|
217
575
|
}
|
|
218
576
|
function generateSoftwareSchema(data) {
|
|
219
|
-
return {
|
|
577
|
+
return cleanSchema({
|
|
220
578
|
"@context": "https://schema.org",
|
|
221
579
|
"@type": "SoftwareApplication",
|
|
222
580
|
"name": data.name,
|
|
@@ -235,10 +593,10 @@ function generateSoftwareSchema(data) {
|
|
|
235
593
|
} : void 0,
|
|
236
594
|
"downloadUrl": data.downloadUrl,
|
|
237
595
|
"screenshot": data.screenshot
|
|
238
|
-
};
|
|
596
|
+
});
|
|
239
597
|
}
|
|
240
598
|
function generateBookSchema(data) {
|
|
241
|
-
return {
|
|
599
|
+
return cleanSchema({
|
|
242
600
|
"@context": "https://schema.org",
|
|
243
601
|
"@type": "Book",
|
|
244
602
|
"name": data.name,
|
|
@@ -261,10 +619,10 @@ function generateBookSchema(data) {
|
|
|
261
619
|
"image": data.image,
|
|
262
620
|
"inLanguage": data.inLanguage,
|
|
263
621
|
"genre": data.genre
|
|
264
|
-
};
|
|
622
|
+
});
|
|
265
623
|
}
|
|
266
624
|
function generateMovieSchema(data) {
|
|
267
|
-
return {
|
|
625
|
+
return cleanSchema({
|
|
268
626
|
"@context": "https://schema.org",
|
|
269
627
|
"@type": "Movie",
|
|
270
628
|
"name": data.name,
|
|
@@ -286,10 +644,10 @@ function generateMovieSchema(data) {
|
|
|
286
644
|
"ratingValue": data.rating,
|
|
287
645
|
"reviewCount": data.reviewCount || 1
|
|
288
646
|
} : void 0
|
|
289
|
-
};
|
|
647
|
+
});
|
|
290
648
|
}
|
|
291
649
|
function generatePodcastSchema(data) {
|
|
292
|
-
return {
|
|
650
|
+
return cleanSchema({
|
|
293
651
|
"@context": "https://schema.org",
|
|
294
652
|
"@type": "PodcastSeries",
|
|
295
653
|
"name": data.name,
|
|
@@ -302,10 +660,10 @@ function generatePodcastSchema(data) {
|
|
|
302
660
|
"webFeed": data.webFeed,
|
|
303
661
|
"url": data.url,
|
|
304
662
|
"genre": data.genre
|
|
305
|
-
};
|
|
663
|
+
});
|
|
306
664
|
}
|
|
307
665
|
function generatePodcastEpisodeSchema(data) {
|
|
308
|
-
return {
|
|
666
|
+
return cleanSchema({
|
|
309
667
|
"@context": "https://schema.org",
|
|
310
668
|
"@type": "PodcastEpisode",
|
|
311
669
|
"name": data.name,
|
|
@@ -322,7 +680,109 @@ function generatePodcastEpisodeSchema(data) {
|
|
|
322
680
|
"name": data.partOfSeries.name,
|
|
323
681
|
"url": data.partOfSeries.url
|
|
324
682
|
} : void 0
|
|
325
|
-
};
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
function generateHowToSchema(data) {
|
|
686
|
+
return cleanSchema({
|
|
687
|
+
"@context": "https://schema.org",
|
|
688
|
+
"@type": "HowTo",
|
|
689
|
+
"name": data.name,
|
|
690
|
+
"description": data.description,
|
|
691
|
+
"image": data.image,
|
|
692
|
+
"totalTime": data.totalTime,
|
|
693
|
+
"estimatedCost": data.estimatedCost ? {
|
|
694
|
+
"@type": "MonetaryAmount",
|
|
695
|
+
"currency": data.estimatedCost.currency,
|
|
696
|
+
"value": data.estimatedCost.value
|
|
697
|
+
} : void 0,
|
|
698
|
+
"supply": data.supply?.map((s) => ({ "@type": "HowToSupply", "name": s })),
|
|
699
|
+
"tool": data.tool?.map((t) => ({ "@type": "HowToTool", "name": t })),
|
|
700
|
+
"step": data.steps.map((step, index) => {
|
|
701
|
+
if (typeof step === "string") {
|
|
702
|
+
return { "@type": "HowToStep", "position": index + 1, "text": step };
|
|
703
|
+
}
|
|
704
|
+
return cleanSchema({
|
|
705
|
+
"@type": "HowToStep",
|
|
706
|
+
"position": index + 1,
|
|
707
|
+
"name": step.name,
|
|
708
|
+
"text": step.text,
|
|
709
|
+
"image": step.image,
|
|
710
|
+
"url": step.url
|
|
711
|
+
});
|
|
712
|
+
})
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
function generateRecipeSchema(data) {
|
|
716
|
+
return cleanSchema({
|
|
717
|
+
"@context": "https://schema.org",
|
|
718
|
+
"@type": "Recipe",
|
|
719
|
+
"name": data.name,
|
|
720
|
+
"description": data.description,
|
|
721
|
+
"image": data.image,
|
|
722
|
+
"author": { "@type": "Person", "name": data.author },
|
|
723
|
+
"datePublished": data.publishedDate,
|
|
724
|
+
"prepTime": data.prepTime,
|
|
725
|
+
"cookTime": data.cookTime,
|
|
726
|
+
"totalTime": data.totalTime,
|
|
727
|
+
"recipeYield": data.recipeYield,
|
|
728
|
+
"recipeCategory": data.recipeCategory,
|
|
729
|
+
"recipeCuisine": data.recipeCuisine,
|
|
730
|
+
"recipeIngredient": data.ingredients,
|
|
731
|
+
"recipeInstructions": data.instructions.map((step) => cleanSchema({
|
|
732
|
+
"@type": "HowToStep",
|
|
733
|
+
"name": step.name,
|
|
734
|
+
"text": step.text,
|
|
735
|
+
"image": step.image
|
|
736
|
+
})),
|
|
737
|
+
"aggregateRating": data.rating ? {
|
|
738
|
+
"@type": "AggregateRating",
|
|
739
|
+
"ratingValue": data.rating,
|
|
740
|
+
"reviewCount": data.reviewCount || 1
|
|
741
|
+
} : void 0
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
function generateJobPostingSchema(data) {
|
|
745
|
+
return cleanSchema({
|
|
746
|
+
"@context": "https://schema.org",
|
|
747
|
+
"@type": "JobPosting",
|
|
748
|
+
"title": data.title,
|
|
749
|
+
"description": data.description,
|
|
750
|
+
"datePosted": data.datePosted,
|
|
751
|
+
"validThrough": data.validThrough,
|
|
752
|
+
"employmentType": data.employmentType,
|
|
753
|
+
"jobLocationType": data.remote ? "TELECOMMUTE" : void 0,
|
|
754
|
+
"hiringOrganization": {
|
|
755
|
+
"@type": "Organization",
|
|
756
|
+
"name": data.hiringOrganization.name,
|
|
757
|
+
"sameAs": data.hiringOrganization.sameAs,
|
|
758
|
+
"logo": data.hiringOrganization.logo
|
|
759
|
+
},
|
|
760
|
+
"jobLocation": {
|
|
761
|
+
"@type": "Place",
|
|
762
|
+
"address": {
|
|
763
|
+
"@type": "PostalAddress",
|
|
764
|
+
"streetAddress": data.jobLocation.streetAddress,
|
|
765
|
+
"addressLocality": data.jobLocation.addressLocality,
|
|
766
|
+
"addressRegion": data.jobLocation.addressRegion,
|
|
767
|
+
"postalCode": data.jobLocation.postalCode,
|
|
768
|
+
"addressCountry": data.jobLocation.addressCountry
|
|
769
|
+
}
|
|
770
|
+
},
|
|
771
|
+
"baseSalary": data.baseSalary ? {
|
|
772
|
+
"@type": "MonetaryAmount",
|
|
773
|
+
"currency": data.baseSalary.currency,
|
|
774
|
+
"value": typeof data.baseSalary.value === "number" ? {
|
|
775
|
+
"@type": "QuantitativeValue",
|
|
776
|
+
"value": data.baseSalary.value,
|
|
777
|
+
"unitText": data.baseSalary.unitText || "MONTH"
|
|
778
|
+
} : {
|
|
779
|
+
"@type": "QuantitativeValue",
|
|
780
|
+
"minValue": data.baseSalary.value.minValue,
|
|
781
|
+
"maxValue": data.baseSalary.value.maxValue,
|
|
782
|
+
"unitText": data.baseSalary.unitText || "MONTH"
|
|
783
|
+
}
|
|
784
|
+
} : void 0
|
|
785
|
+
});
|
|
326
786
|
}
|
|
327
787
|
|
|
328
788
|
// src/core/metadata.ts
|
|
@@ -366,6 +826,9 @@ function toNextMetadata(props, config) {
|
|
|
366
826
|
},
|
|
367
827
|
other: {}
|
|
368
828
|
};
|
|
829
|
+
if (config.facebookAppId) {
|
|
830
|
+
metadata.other["fb:app_id"] = config.facebookAppId;
|
|
831
|
+
}
|
|
369
832
|
if (props.alternates && props.alternates.length > 0) {
|
|
370
833
|
const languages = {};
|
|
371
834
|
props.alternates.forEach((alt) => {
|
|
@@ -373,6 +836,12 @@ function toNextMetadata(props, config) {
|
|
|
373
836
|
});
|
|
374
837
|
metadata.alternates.languages = languages;
|
|
375
838
|
}
|
|
839
|
+
if (props.prev) {
|
|
840
|
+
metadata.alternates.prev = props.prev;
|
|
841
|
+
}
|
|
842
|
+
if (props.next) {
|
|
843
|
+
metadata.alternates.next = props.next;
|
|
844
|
+
}
|
|
376
845
|
metadata.appleWebApp = {
|
|
377
846
|
capable: true,
|
|
378
847
|
title: config.name,
|
|
@@ -380,6 +849,45 @@ function toNextMetadata(props, config) {
|
|
|
380
849
|
};
|
|
381
850
|
if (config.themeColor) metadata.themeColor = config.themeColor;
|
|
382
851
|
if (config.manifest) metadata.manifest = config.manifest;
|
|
852
|
+
if (props.type === "article") {
|
|
853
|
+
if (props.publishedTime) {
|
|
854
|
+
metadata.openGraph.publishedTime = props.publishedTime;
|
|
855
|
+
}
|
|
856
|
+
if (props.modifiedTime) {
|
|
857
|
+
metadata.openGraph.modifiedTime = props.modifiedTime;
|
|
858
|
+
}
|
|
859
|
+
if (props.author) {
|
|
860
|
+
metadata.openGraph.authors = [props.author.name];
|
|
861
|
+
}
|
|
862
|
+
if (props.section) {
|
|
863
|
+
metadata.openGraph.section = props.section;
|
|
864
|
+
}
|
|
865
|
+
if (props.tags?.length) {
|
|
866
|
+
metadata.openGraph.tags = props.tags;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
if (props.type === "product" && props.product) {
|
|
870
|
+
if (props.product.price !== void 0 && props.product.currency) {
|
|
871
|
+
metadata.other["product:price:amount"] = props.product.price.toString();
|
|
872
|
+
metadata.other["product:price:currency"] = props.product.currency;
|
|
873
|
+
}
|
|
874
|
+
if (props.product.availability) {
|
|
875
|
+
metadata.other["product:availability"] = props.product.availability;
|
|
876
|
+
}
|
|
877
|
+
if (props.product.brand) {
|
|
878
|
+
metadata.other["product:brand"] = props.product.brand;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
if (props.readingTime) {
|
|
882
|
+
metadata.other["twitter:label1"] = "Reading time";
|
|
883
|
+
metadata.other["twitter:data1"] = `${props.readingTime} min`;
|
|
884
|
+
}
|
|
885
|
+
if (props.whatsappImage) {
|
|
886
|
+
metadata.other["og:image:secure_url"] = props.whatsappImage;
|
|
887
|
+
}
|
|
888
|
+
if (Object.keys(metadata.other).length === 0) {
|
|
889
|
+
delete metadata.other;
|
|
890
|
+
}
|
|
383
891
|
return metadata;
|
|
384
892
|
}
|
|
385
893
|
function generatePaginationLinks(baseUrl, currentPage, totalPages) {
|
|
@@ -392,20 +900,1116 @@ function generatePaginationLinks(baseUrl, currentPage, totalPages) {
|
|
|
392
900
|
canonical: currentPage === 1 ? cleanBase : `${cleanBase}?page=${currentPage}`
|
|
393
901
|
};
|
|
394
902
|
}
|
|
395
|
-
function generatePaginatedTitle(title, page, suffix = "
|
|
903
|
+
function generatePaginatedTitle(title, page, suffix = "Page") {
|
|
396
904
|
return page > 1 ? `${title} - ${suffix} ${page}` : title;
|
|
397
905
|
}
|
|
398
906
|
|
|
399
|
-
// src/
|
|
400
|
-
var import_react = require("react");
|
|
401
|
-
var import_react_helmet_async = require("react-helmet-async");
|
|
907
|
+
// src/core/JsonLd.tsx
|
|
402
908
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
403
|
-
|
|
909
|
+
function JsonLd({ schema, graph = false }) {
|
|
910
|
+
const schemas = Array.isArray(schema) ? schema : [schema];
|
|
911
|
+
if (graph && schemas.length > 1) {
|
|
912
|
+
const graphData = {
|
|
913
|
+
"@context": "https://schema.org",
|
|
914
|
+
"@graph": schemas.map((s) => {
|
|
915
|
+
const { "@context": _, ...rest } = s;
|
|
916
|
+
return rest;
|
|
917
|
+
})
|
|
918
|
+
};
|
|
919
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
920
|
+
"script",
|
|
921
|
+
{
|
|
922
|
+
type: "application/ld+json",
|
|
923
|
+
dangerouslySetInnerHTML: { __html: JSON.stringify(graphData) }
|
|
924
|
+
}
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: schemas.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
928
|
+
"script",
|
|
929
|
+
{
|
|
930
|
+
type: "application/ld+json",
|
|
931
|
+
dangerouslySetInnerHTML: { __html: JSON.stringify(s) }
|
|
932
|
+
},
|
|
933
|
+
i
|
|
934
|
+
)) });
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
// src/core/product-metadata.ts
|
|
938
|
+
function generateProductMetadata(product, config) {
|
|
939
|
+
const primaryImage = Array.isArray(product.image) ? product.image[0] : product.image;
|
|
940
|
+
const seoData = {
|
|
941
|
+
title: product.metaTitle || product.name,
|
|
942
|
+
description: product.metaDescription || product.description,
|
|
943
|
+
image: product.ogImage || primaryImage,
|
|
944
|
+
canonical: product.canonical || product.url,
|
|
945
|
+
type: "product",
|
|
946
|
+
noindex: product.noindex,
|
|
947
|
+
ogTitle: product.name,
|
|
948
|
+
ogDescription: product.description,
|
|
949
|
+
ogImage: product.ogImage || primaryImage,
|
|
950
|
+
ogImageWidth: product.ogImageWidth || 1200,
|
|
951
|
+
ogImageHeight: product.ogImageHeight || 630,
|
|
952
|
+
ogType: "product",
|
|
953
|
+
product: {
|
|
954
|
+
sku: product.sku,
|
|
955
|
+
brand: product.brand,
|
|
956
|
+
price: product.price,
|
|
957
|
+
currency: product.currency,
|
|
958
|
+
availability: product.availability,
|
|
959
|
+
rating: product.rating,
|
|
960
|
+
reviewCount: product.reviewCount
|
|
961
|
+
}
|
|
962
|
+
};
|
|
963
|
+
const metadata = toNextMetadata(seoData, config);
|
|
964
|
+
if (product.price !== void 0 && product.currency) {
|
|
965
|
+
metadata.other = {
|
|
966
|
+
...metadata.other,
|
|
967
|
+
"product:price:amount": product.price.toString(),
|
|
968
|
+
"product:price:currency": product.currency
|
|
969
|
+
};
|
|
970
|
+
if (product.availability) {
|
|
971
|
+
metadata.other["product:availability"] = product.availability;
|
|
972
|
+
}
|
|
973
|
+
if (product.brand) {
|
|
974
|
+
metadata.other["product:brand"] = product.brand;
|
|
975
|
+
}
|
|
976
|
+
if (product.condition) {
|
|
977
|
+
metadata.other["product:condition"] = product.condition;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
const productSchema = generateProductSchema({
|
|
981
|
+
name: product.name,
|
|
982
|
+
description: product.description,
|
|
983
|
+
image: product.image,
|
|
984
|
+
sku: product.sku,
|
|
985
|
+
gtin: product.gtin,
|
|
986
|
+
mpn: product.mpn,
|
|
987
|
+
brand: product.brand,
|
|
988
|
+
price: product.price,
|
|
989
|
+
currency: product.currency,
|
|
990
|
+
availability: product.availability,
|
|
991
|
+
rating: product.rating,
|
|
992
|
+
reviewCount: product.reviewCount,
|
|
993
|
+
url: product.url,
|
|
994
|
+
condition: product.condition,
|
|
995
|
+
reviews: product.reviews,
|
|
996
|
+
returnPolicy: product.returnPolicy,
|
|
997
|
+
shipping: product.shipping,
|
|
998
|
+
variants: product.variants,
|
|
999
|
+
seller: product.seller
|
|
1000
|
+
});
|
|
1001
|
+
const breadcrumbItems = product.breadcrumbs || [
|
|
1002
|
+
{ name: "Home", item: config.url },
|
|
1003
|
+
{ name: "Shop", item: `${config.url}/shop` },
|
|
1004
|
+
...product.category ? [{ name: product.category, item: `${config.url}/categories/${encodeURIComponent(product.category)}` }] : [],
|
|
1005
|
+
{ name: product.name, item: product.url }
|
|
1006
|
+
];
|
|
1007
|
+
const breadcrumbSchema = generateBreadcrumbSchema(breadcrumbItems);
|
|
1008
|
+
const organizationSchema = generateOrganizationSchema(config);
|
|
1009
|
+
const websiteSchema = generateWebSiteSchema(config);
|
|
1010
|
+
return {
|
|
1011
|
+
metadata,
|
|
1012
|
+
schemas: [productSchema, breadcrumbSchema, organizationSchema, websiteSchema],
|
|
1013
|
+
productSchema,
|
|
1014
|
+
breadcrumbSchema,
|
|
1015
|
+
organizationSchema,
|
|
1016
|
+
websiteSchema
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
// src/core/article-metadata.ts
|
|
1021
|
+
function generateArticleMetadata(article, config) {
|
|
1022
|
+
const primaryImage = Array.isArray(article.image) ? article.image[0] : article.image;
|
|
1023
|
+
const seoData = {
|
|
1024
|
+
title: article.metaTitle || article.title,
|
|
1025
|
+
description: article.metaDescription || article.description,
|
|
1026
|
+
image: article.ogImage || primaryImage,
|
|
1027
|
+
canonical: article.canonical || article.url,
|
|
1028
|
+
type: "article",
|
|
1029
|
+
noindex: article.noindex,
|
|
1030
|
+
publishedTime: article.publishedTime,
|
|
1031
|
+
modifiedTime: article.modifiedTime,
|
|
1032
|
+
author: article.author,
|
|
1033
|
+
section: article.category,
|
|
1034
|
+
tags: article.tags,
|
|
1035
|
+
readingTime: article.readingTime,
|
|
1036
|
+
ogTitle: article.title,
|
|
1037
|
+
ogDescription: article.description,
|
|
1038
|
+
ogImage: article.ogImage || primaryImage,
|
|
1039
|
+
ogImageWidth: article.ogImageWidth || 1200,
|
|
1040
|
+
ogImageHeight: article.ogImageHeight || 630,
|
|
1041
|
+
ogType: "article"
|
|
1042
|
+
};
|
|
1043
|
+
const metadata = toNextMetadata(seoData, config);
|
|
1044
|
+
if (article.publishedTime) {
|
|
1045
|
+
metadata.other = {
|
|
1046
|
+
...metadata.other,
|
|
1047
|
+
"article:published_time": article.publishedTime
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
if (article.modifiedTime) {
|
|
1051
|
+
metadata.other = {
|
|
1052
|
+
...metadata.other,
|
|
1053
|
+
"article:modified_time": article.modifiedTime
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
if (article.category) {
|
|
1057
|
+
metadata.other = {
|
|
1058
|
+
...metadata.other,
|
|
1059
|
+
"article:section": article.category
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
if (article.tags?.length) {
|
|
1063
|
+
metadata.other = {
|
|
1064
|
+
...metadata.other,
|
|
1065
|
+
"article:tag": article.tags.join(",")
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
const articleSchema = generateArticleSchema({
|
|
1069
|
+
title: article.title,
|
|
1070
|
+
description: article.description,
|
|
1071
|
+
image: article.image,
|
|
1072
|
+
publishedTime: article.publishedTime,
|
|
1073
|
+
modifiedTime: article.modifiedTime,
|
|
1074
|
+
author: article.author,
|
|
1075
|
+
url: article.url,
|
|
1076
|
+
wordCount: article.wordCount
|
|
1077
|
+
}, config);
|
|
1078
|
+
const breadcrumbItems = article.breadcrumbs || [
|
|
1079
|
+
{ name: "Home", item: config.url },
|
|
1080
|
+
...article.category ? [{ name: article.category, item: `${config.url}/category/${encodeURIComponent(article.category)}` }] : [],
|
|
1081
|
+
{ name: article.title, item: article.url }
|
|
1082
|
+
];
|
|
1083
|
+
const breadcrumbSchema = generateBreadcrumbSchema(breadcrumbItems);
|
|
1084
|
+
const organizationSchema = generateOrganizationSchema(config);
|
|
1085
|
+
const websiteSchema = generateWebSiteSchema(config);
|
|
1086
|
+
return {
|
|
1087
|
+
metadata,
|
|
1088
|
+
schemas: [articleSchema, breadcrumbSchema, organizationSchema, websiteSchema],
|
|
1089
|
+
articleSchema,
|
|
1090
|
+
breadcrumbSchema,
|
|
1091
|
+
organizationSchema,
|
|
1092
|
+
websiteSchema
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// src/core/category-metadata.ts
|
|
1097
|
+
function generateCategoryMetadata(category, config) {
|
|
1098
|
+
const page = category.page || 1;
|
|
1099
|
+
const totalPages = category.totalPages || 1;
|
|
1100
|
+
const pageSuffix = category.pageSuffix || "Page";
|
|
1101
|
+
const pagination = generatePaginationLinks(category.url, page, totalPages);
|
|
1102
|
+
const title = generatePaginatedTitle(
|
|
1103
|
+
category.metaTitle || category.name,
|
|
1104
|
+
page,
|
|
1105
|
+
pageSuffix
|
|
1106
|
+
);
|
|
1107
|
+
const seoData = {
|
|
1108
|
+
title,
|
|
1109
|
+
description: category.metaDescription || category.description,
|
|
1110
|
+
image: category.image,
|
|
1111
|
+
canonical: pagination.canonical,
|
|
1112
|
+
type: "website",
|
|
1113
|
+
noindex: category.noindex,
|
|
1114
|
+
prev: pagination.prev,
|
|
1115
|
+
next: pagination.next
|
|
1116
|
+
};
|
|
1117
|
+
const metadata = toNextMetadata(seoData, config);
|
|
1118
|
+
const collectionPageSchema = generateCollectionPageSchema({
|
|
1119
|
+
name: category.name,
|
|
1120
|
+
description: category.description,
|
|
1121
|
+
url: pagination.canonical || category.url,
|
|
1122
|
+
image: category.image,
|
|
1123
|
+
numberOfItems: category.items?.length
|
|
1124
|
+
}, config);
|
|
1125
|
+
const breadcrumbItems = category.breadcrumbs || [
|
|
1126
|
+
{ name: "Home", item: config.url },
|
|
1127
|
+
...category.parentCategory ? [{ name: category.parentCategory, item: `${config.url}/categories` }] : [],
|
|
1128
|
+
{ name: category.name, item: category.url }
|
|
1129
|
+
];
|
|
1130
|
+
const breadcrumbSchema = generateBreadcrumbSchema(breadcrumbItems);
|
|
1131
|
+
const organizationSchema = generateOrganizationSchema(config);
|
|
1132
|
+
let itemListSchema;
|
|
1133
|
+
if (category.items && category.items.length > 0) {
|
|
1134
|
+
itemListSchema = generateItemListSchema({
|
|
1135
|
+
name: category.name,
|
|
1136
|
+
url: pagination.canonical || category.url,
|
|
1137
|
+
items: category.items
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
const schemas = [collectionPageSchema, breadcrumbSchema, organizationSchema];
|
|
1141
|
+
if (itemListSchema) schemas.push(itemListSchema);
|
|
1142
|
+
return {
|
|
1143
|
+
metadata,
|
|
1144
|
+
schemas,
|
|
1145
|
+
collectionPageSchema,
|
|
1146
|
+
breadcrumbSchema,
|
|
1147
|
+
organizationSchema,
|
|
1148
|
+
itemListSchema
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
// src/core/homepage-metadata.ts
|
|
1153
|
+
function generateHomepageMetadata(input, config) {
|
|
1154
|
+
const seoData = {
|
|
1155
|
+
title: input.title || config.name,
|
|
1156
|
+
description: input.description || config.description,
|
|
1157
|
+
image: input.ogImage || input.image || config.logo,
|
|
1158
|
+
canonical: input.canonical || config.url,
|
|
1159
|
+
type: "website",
|
|
1160
|
+
ogTitle: input.title || config.name,
|
|
1161
|
+
ogDescription: input.description || config.description,
|
|
1162
|
+
ogImage: input.ogImage || input.image || config.logo,
|
|
1163
|
+
ogImageWidth: input.ogImageWidth || 1200,
|
|
1164
|
+
ogImageHeight: input.ogImageHeight || 630
|
|
1165
|
+
};
|
|
1166
|
+
const metadata = toNextMetadata(seoData, config);
|
|
1167
|
+
const webPageSchema = generateWebPageSchema({
|
|
1168
|
+
name: input.title || config.name,
|
|
1169
|
+
description: input.description || config.description,
|
|
1170
|
+
url: config.url,
|
|
1171
|
+
image: input.image || config.logo
|
|
1172
|
+
}, config);
|
|
1173
|
+
const organizationSchema = generateOrganizationSchema({
|
|
1174
|
+
...config,
|
|
1175
|
+
socialLinks: input.socialLinks || config.socialLinks
|
|
1176
|
+
});
|
|
1177
|
+
const websiteSchema = generateWebSiteSchema(config);
|
|
1178
|
+
const schemas = [webPageSchema, organizationSchema, websiteSchema];
|
|
1179
|
+
let localBusinessSchema;
|
|
1180
|
+
if (input.localBusiness) {
|
|
1181
|
+
localBusinessSchema = generateLocalBusinessSchema(input.localBusiness);
|
|
1182
|
+
schemas.push(localBusinessSchema);
|
|
1183
|
+
}
|
|
1184
|
+
return {
|
|
1185
|
+
metadata,
|
|
1186
|
+
schemas,
|
|
1187
|
+
webPageSchema,
|
|
1188
|
+
organizationSchema,
|
|
1189
|
+
websiteSchema,
|
|
1190
|
+
localBusinessSchema
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
// src/components/SEOProvider.tsx
|
|
1195
|
+
var import_react5 = require("react");
|
|
1196
|
+
|
|
1197
|
+
// node_modules/react-helmet-async/lib/index.esm.js
|
|
1198
|
+
var import_react = __toESM(require("react"));
|
|
1199
|
+
var import_react_fast_compare = __toESM(require_react_fast_compare());
|
|
1200
|
+
var import_invariant = __toESM(require_invariant());
|
|
1201
|
+
var import_react2 = __toESM(require("react"));
|
|
1202
|
+
var import_react3 = __toESM(require("react"));
|
|
1203
|
+
var import_react4 = require("react");
|
|
1204
|
+
var import_shallowequal = __toESM(require_shallowequal());
|
|
1205
|
+
var TAG_NAMES = /* @__PURE__ */ ((TAG_NAMES2) => {
|
|
1206
|
+
TAG_NAMES2["BASE"] = "base";
|
|
1207
|
+
TAG_NAMES2["BODY"] = "body";
|
|
1208
|
+
TAG_NAMES2["HEAD"] = "head";
|
|
1209
|
+
TAG_NAMES2["HTML"] = "html";
|
|
1210
|
+
TAG_NAMES2["LINK"] = "link";
|
|
1211
|
+
TAG_NAMES2["META"] = "meta";
|
|
1212
|
+
TAG_NAMES2["NOSCRIPT"] = "noscript";
|
|
1213
|
+
TAG_NAMES2["SCRIPT"] = "script";
|
|
1214
|
+
TAG_NAMES2["STYLE"] = "style";
|
|
1215
|
+
TAG_NAMES2["TITLE"] = "title";
|
|
1216
|
+
TAG_NAMES2["FRAGMENT"] = "Symbol(react.fragment)";
|
|
1217
|
+
return TAG_NAMES2;
|
|
1218
|
+
})(TAG_NAMES || {});
|
|
1219
|
+
var SEO_PRIORITY_TAGS = {
|
|
1220
|
+
link: { rel: ["amphtml", "canonical", "alternate"] },
|
|
1221
|
+
script: { type: ["application/ld+json"] },
|
|
1222
|
+
meta: {
|
|
1223
|
+
charset: "",
|
|
1224
|
+
name: ["generator", "robots", "description"],
|
|
1225
|
+
property: [
|
|
1226
|
+
"og:type",
|
|
1227
|
+
"og:title",
|
|
1228
|
+
"og:url",
|
|
1229
|
+
"og:image",
|
|
1230
|
+
"og:image:alt",
|
|
1231
|
+
"og:description",
|
|
1232
|
+
"twitter:url",
|
|
1233
|
+
"twitter:title",
|
|
1234
|
+
"twitter:description",
|
|
1235
|
+
"twitter:image",
|
|
1236
|
+
"twitter:image:alt",
|
|
1237
|
+
"twitter:card",
|
|
1238
|
+
"twitter:site"
|
|
1239
|
+
]
|
|
1240
|
+
}
|
|
1241
|
+
};
|
|
1242
|
+
var VALID_TAG_NAMES = Object.values(TAG_NAMES);
|
|
1243
|
+
var REACT_TAG_MAP = {
|
|
1244
|
+
accesskey: "accessKey",
|
|
1245
|
+
charset: "charSet",
|
|
1246
|
+
class: "className",
|
|
1247
|
+
contenteditable: "contentEditable",
|
|
1248
|
+
contextmenu: "contextMenu",
|
|
1249
|
+
"http-equiv": "httpEquiv",
|
|
1250
|
+
itemprop: "itemProp",
|
|
1251
|
+
tabindex: "tabIndex"
|
|
1252
|
+
};
|
|
1253
|
+
var HTML_TAG_MAP = Object.entries(REACT_TAG_MAP).reduce(
|
|
1254
|
+
(carry, [key, value]) => {
|
|
1255
|
+
carry[value] = key;
|
|
1256
|
+
return carry;
|
|
1257
|
+
},
|
|
1258
|
+
{}
|
|
1259
|
+
);
|
|
1260
|
+
var HELMET_ATTRIBUTE = "data-rh";
|
|
1261
|
+
var HELMET_PROPS = {
|
|
1262
|
+
DEFAULT_TITLE: "defaultTitle",
|
|
1263
|
+
DEFER: "defer",
|
|
1264
|
+
ENCODE_SPECIAL_CHARACTERS: "encodeSpecialCharacters",
|
|
1265
|
+
ON_CHANGE_CLIENT_STATE: "onChangeClientState",
|
|
1266
|
+
TITLE_TEMPLATE: "titleTemplate",
|
|
1267
|
+
PRIORITIZE_SEO_TAGS: "prioritizeSeoTags"
|
|
1268
|
+
};
|
|
1269
|
+
var getInnermostProperty = (propsList, property) => {
|
|
1270
|
+
for (let i = propsList.length - 1; i >= 0; i -= 1) {
|
|
1271
|
+
const props = propsList[i];
|
|
1272
|
+
if (Object.prototype.hasOwnProperty.call(props, property)) {
|
|
1273
|
+
return props[property];
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
return null;
|
|
1277
|
+
};
|
|
1278
|
+
var getTitleFromPropsList = (propsList) => {
|
|
1279
|
+
let innermostTitle = getInnermostProperty(
|
|
1280
|
+
propsList,
|
|
1281
|
+
"title"
|
|
1282
|
+
/* TITLE */
|
|
1283
|
+
);
|
|
1284
|
+
const innermostTemplate = getInnermostProperty(propsList, HELMET_PROPS.TITLE_TEMPLATE);
|
|
1285
|
+
if (Array.isArray(innermostTitle)) {
|
|
1286
|
+
innermostTitle = innermostTitle.join("");
|
|
1287
|
+
}
|
|
1288
|
+
if (innermostTemplate && innermostTitle) {
|
|
1289
|
+
return innermostTemplate.replace(/%s/g, () => innermostTitle);
|
|
1290
|
+
}
|
|
1291
|
+
const innermostDefaultTitle = getInnermostProperty(propsList, HELMET_PROPS.DEFAULT_TITLE);
|
|
1292
|
+
return innermostTitle || innermostDefaultTitle || void 0;
|
|
1293
|
+
};
|
|
1294
|
+
var getOnChangeClientState = (propsList) => getInnermostProperty(propsList, HELMET_PROPS.ON_CHANGE_CLIENT_STATE) || (() => {
|
|
1295
|
+
});
|
|
1296
|
+
var getAttributesFromPropsList = (tagType, propsList) => propsList.filter((props) => typeof props[tagType] !== "undefined").map((props) => props[tagType]).reduce((tagAttrs, current) => ({ ...tagAttrs, ...current }), {});
|
|
1297
|
+
var getBaseTagFromPropsList = (primaryAttributes, propsList) => propsList.filter((props) => typeof props[
|
|
1298
|
+
"base"
|
|
1299
|
+
/* BASE */
|
|
1300
|
+
] !== "undefined").map((props) => props[
|
|
1301
|
+
"base"
|
|
1302
|
+
/* BASE */
|
|
1303
|
+
]).reverse().reduce((innermostBaseTag, tag) => {
|
|
1304
|
+
if (!innermostBaseTag.length) {
|
|
1305
|
+
const keys = Object.keys(tag);
|
|
1306
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
1307
|
+
const attributeKey = keys[i];
|
|
1308
|
+
const lowerCaseAttributeKey = attributeKey.toLowerCase();
|
|
1309
|
+
if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && tag[lowerCaseAttributeKey]) {
|
|
1310
|
+
return innermostBaseTag.concat(tag);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
return innermostBaseTag;
|
|
1315
|
+
}, []);
|
|
1316
|
+
var warn = (msg) => console && typeof console.warn === "function" && console.warn(msg);
|
|
1317
|
+
var getTagsFromPropsList = (tagName, primaryAttributes, propsList) => {
|
|
1318
|
+
const approvedSeenTags = {};
|
|
1319
|
+
return propsList.filter((props) => {
|
|
1320
|
+
if (Array.isArray(props[tagName])) {
|
|
1321
|
+
return true;
|
|
1322
|
+
}
|
|
1323
|
+
if (typeof props[tagName] !== "undefined") {
|
|
1324
|
+
warn(
|
|
1325
|
+
`Helmet: ${tagName} should be of type "Array". Instead found type "${typeof props[tagName]}"`
|
|
1326
|
+
);
|
|
1327
|
+
}
|
|
1328
|
+
return false;
|
|
1329
|
+
}).map((props) => props[tagName]).reverse().reduce((approvedTags, instanceTags) => {
|
|
1330
|
+
const instanceSeenTags = {};
|
|
1331
|
+
instanceTags.filter((tag) => {
|
|
1332
|
+
let primaryAttributeKey;
|
|
1333
|
+
const keys2 = Object.keys(tag);
|
|
1334
|
+
for (let i = 0; i < keys2.length; i += 1) {
|
|
1335
|
+
const attributeKey = keys2[i];
|
|
1336
|
+
const lowerCaseAttributeKey = attributeKey.toLowerCase();
|
|
1337
|
+
if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && !(primaryAttributeKey === "rel" && tag[primaryAttributeKey].toLowerCase() === "canonical") && !(lowerCaseAttributeKey === "rel" && tag[lowerCaseAttributeKey].toLowerCase() === "stylesheet")) {
|
|
1338
|
+
primaryAttributeKey = lowerCaseAttributeKey;
|
|
1339
|
+
}
|
|
1340
|
+
if (primaryAttributes.indexOf(attributeKey) !== -1 && (attributeKey === "innerHTML" || attributeKey === "cssText" || attributeKey === "itemprop")) {
|
|
1341
|
+
primaryAttributeKey = attributeKey;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
if (!primaryAttributeKey || !tag[primaryAttributeKey]) {
|
|
1345
|
+
return false;
|
|
1346
|
+
}
|
|
1347
|
+
const value = tag[primaryAttributeKey].toLowerCase();
|
|
1348
|
+
if (!approvedSeenTags[primaryAttributeKey]) {
|
|
1349
|
+
approvedSeenTags[primaryAttributeKey] = {};
|
|
1350
|
+
}
|
|
1351
|
+
if (!instanceSeenTags[primaryAttributeKey]) {
|
|
1352
|
+
instanceSeenTags[primaryAttributeKey] = {};
|
|
1353
|
+
}
|
|
1354
|
+
if (!approvedSeenTags[primaryAttributeKey][value]) {
|
|
1355
|
+
instanceSeenTags[primaryAttributeKey][value] = true;
|
|
1356
|
+
return true;
|
|
1357
|
+
}
|
|
1358
|
+
return false;
|
|
1359
|
+
}).reverse().forEach((tag) => approvedTags.push(tag));
|
|
1360
|
+
const keys = Object.keys(instanceSeenTags);
|
|
1361
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
1362
|
+
const attributeKey = keys[i];
|
|
1363
|
+
const tagUnion = {
|
|
1364
|
+
...approvedSeenTags[attributeKey],
|
|
1365
|
+
...instanceSeenTags[attributeKey]
|
|
1366
|
+
};
|
|
1367
|
+
approvedSeenTags[attributeKey] = tagUnion;
|
|
1368
|
+
}
|
|
1369
|
+
return approvedTags;
|
|
1370
|
+
}, []).reverse();
|
|
1371
|
+
};
|
|
1372
|
+
var getAnyTrueFromPropsList = (propsList, checkedTag) => {
|
|
1373
|
+
if (Array.isArray(propsList) && propsList.length) {
|
|
1374
|
+
for (let index = 0; index < propsList.length; index += 1) {
|
|
1375
|
+
const prop = propsList[index];
|
|
1376
|
+
if (prop[checkedTag]) {
|
|
1377
|
+
return true;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
return false;
|
|
1382
|
+
};
|
|
1383
|
+
var reducePropsToState = (propsList) => ({
|
|
1384
|
+
baseTag: getBaseTagFromPropsList([
|
|
1385
|
+
"href"
|
|
1386
|
+
/* HREF */
|
|
1387
|
+
], propsList),
|
|
1388
|
+
bodyAttributes: getAttributesFromPropsList("bodyAttributes", propsList),
|
|
1389
|
+
defer: getInnermostProperty(propsList, HELMET_PROPS.DEFER),
|
|
1390
|
+
encode: getInnermostProperty(propsList, HELMET_PROPS.ENCODE_SPECIAL_CHARACTERS),
|
|
1391
|
+
htmlAttributes: getAttributesFromPropsList("htmlAttributes", propsList),
|
|
1392
|
+
linkTags: getTagsFromPropsList(
|
|
1393
|
+
"link",
|
|
1394
|
+
[
|
|
1395
|
+
"rel",
|
|
1396
|
+
"href"
|
|
1397
|
+
/* HREF */
|
|
1398
|
+
],
|
|
1399
|
+
propsList
|
|
1400
|
+
),
|
|
1401
|
+
metaTags: getTagsFromPropsList(
|
|
1402
|
+
"meta",
|
|
1403
|
+
[
|
|
1404
|
+
"name",
|
|
1405
|
+
"charset",
|
|
1406
|
+
"http-equiv",
|
|
1407
|
+
"property",
|
|
1408
|
+
"itemprop"
|
|
1409
|
+
/* ITEM_PROP */
|
|
1410
|
+
],
|
|
1411
|
+
propsList
|
|
1412
|
+
),
|
|
1413
|
+
noscriptTags: getTagsFromPropsList("noscript", [
|
|
1414
|
+
"innerHTML"
|
|
1415
|
+
/* INNER_HTML */
|
|
1416
|
+
], propsList),
|
|
1417
|
+
onChangeClientState: getOnChangeClientState(propsList),
|
|
1418
|
+
scriptTags: getTagsFromPropsList(
|
|
1419
|
+
"script",
|
|
1420
|
+
[
|
|
1421
|
+
"src",
|
|
1422
|
+
"innerHTML"
|
|
1423
|
+
/* INNER_HTML */
|
|
1424
|
+
],
|
|
1425
|
+
propsList
|
|
1426
|
+
),
|
|
1427
|
+
styleTags: getTagsFromPropsList("style", [
|
|
1428
|
+
"cssText"
|
|
1429
|
+
/* CSS_TEXT */
|
|
1430
|
+
], propsList),
|
|
1431
|
+
title: getTitleFromPropsList(propsList),
|
|
1432
|
+
titleAttributes: getAttributesFromPropsList("titleAttributes", propsList),
|
|
1433
|
+
prioritizeSeoTags: getAnyTrueFromPropsList(propsList, HELMET_PROPS.PRIORITIZE_SEO_TAGS)
|
|
1434
|
+
});
|
|
1435
|
+
var flattenArray = (possibleArray) => Array.isArray(possibleArray) ? possibleArray.join("") : possibleArray;
|
|
1436
|
+
var checkIfPropsMatch = (props, toMatch) => {
|
|
1437
|
+
const keys = Object.keys(props);
|
|
1438
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
1439
|
+
if (toMatch[keys[i]] && toMatch[keys[i]].includes(props[keys[i]])) {
|
|
1440
|
+
return true;
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
return false;
|
|
1444
|
+
};
|
|
1445
|
+
var prioritizer = (elementsList, propsToMatch) => {
|
|
1446
|
+
if (Array.isArray(elementsList)) {
|
|
1447
|
+
return elementsList.reduce(
|
|
1448
|
+
(acc, elementAttrs) => {
|
|
1449
|
+
if (checkIfPropsMatch(elementAttrs, propsToMatch)) {
|
|
1450
|
+
acc.priority.push(elementAttrs);
|
|
1451
|
+
} else {
|
|
1452
|
+
acc.default.push(elementAttrs);
|
|
1453
|
+
}
|
|
1454
|
+
return acc;
|
|
1455
|
+
},
|
|
1456
|
+
{ priority: [], default: [] }
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
return { default: elementsList, priority: [] };
|
|
1460
|
+
};
|
|
1461
|
+
var without = (obj, key) => {
|
|
1462
|
+
return {
|
|
1463
|
+
...obj,
|
|
1464
|
+
[key]: void 0
|
|
1465
|
+
};
|
|
1466
|
+
};
|
|
1467
|
+
var SELF_CLOSING_TAGS = [
|
|
1468
|
+
"noscript",
|
|
1469
|
+
"script",
|
|
1470
|
+
"style"
|
|
1471
|
+
/* STYLE */
|
|
1472
|
+
];
|
|
1473
|
+
var encodeSpecialCharacters = (str, encode = true) => {
|
|
1474
|
+
if (encode === false) {
|
|
1475
|
+
return String(str);
|
|
1476
|
+
}
|
|
1477
|
+
return String(str).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1478
|
+
};
|
|
1479
|
+
var generateElementAttributesAsString = (attributes) => Object.keys(attributes).reduce((str, key) => {
|
|
1480
|
+
const attr = typeof attributes[key] !== "undefined" ? `${key}="${attributes[key]}"` : `${key}`;
|
|
1481
|
+
return str ? `${str} ${attr}` : attr;
|
|
1482
|
+
}, "");
|
|
1483
|
+
var generateTitleAsString = (type, title, attributes, encode) => {
|
|
1484
|
+
const attributeString = generateElementAttributesAsString(attributes);
|
|
1485
|
+
const flattenedTitle = flattenArray(title);
|
|
1486
|
+
return attributeString ? `<${type} ${HELMET_ATTRIBUTE}="true" ${attributeString}>${encodeSpecialCharacters(
|
|
1487
|
+
flattenedTitle,
|
|
1488
|
+
encode
|
|
1489
|
+
)}</${type}>` : `<${type} ${HELMET_ATTRIBUTE}="true">${encodeSpecialCharacters(
|
|
1490
|
+
flattenedTitle,
|
|
1491
|
+
encode
|
|
1492
|
+
)}</${type}>`;
|
|
1493
|
+
};
|
|
1494
|
+
var generateTagsAsString = (type, tags, encode = true) => tags.reduce((str, t) => {
|
|
1495
|
+
const tag = t;
|
|
1496
|
+
const attributeHtml = Object.keys(tag).filter(
|
|
1497
|
+
(attribute) => !(attribute === "innerHTML" || attribute === "cssText")
|
|
1498
|
+
).reduce((string, attribute) => {
|
|
1499
|
+
const attr = typeof tag[attribute] === "undefined" ? attribute : `${attribute}="${encodeSpecialCharacters(tag[attribute], encode)}"`;
|
|
1500
|
+
return string ? `${string} ${attr}` : attr;
|
|
1501
|
+
}, "");
|
|
1502
|
+
const tagContent = tag.innerHTML || tag.cssText || "";
|
|
1503
|
+
const isSelfClosing = SELF_CLOSING_TAGS.indexOf(type) === -1;
|
|
1504
|
+
return `${str}<${type} ${HELMET_ATTRIBUTE}="true" ${attributeHtml}${isSelfClosing ? `/>` : `>${tagContent}</${type}>`}`;
|
|
1505
|
+
}, "");
|
|
1506
|
+
var convertElementAttributesToReactProps = (attributes, initProps = {}) => Object.keys(attributes).reduce((obj, key) => {
|
|
1507
|
+
const mapped = REACT_TAG_MAP[key];
|
|
1508
|
+
obj[mapped || key] = attributes[key];
|
|
1509
|
+
return obj;
|
|
1510
|
+
}, initProps);
|
|
1511
|
+
var generateTitleAsReactComponent = (_type, title, attributes) => {
|
|
1512
|
+
const initProps = {
|
|
1513
|
+
key: title,
|
|
1514
|
+
[HELMET_ATTRIBUTE]: true
|
|
1515
|
+
};
|
|
1516
|
+
const props = convertElementAttributesToReactProps(attributes, initProps);
|
|
1517
|
+
return [import_react3.default.createElement("title", props, title)];
|
|
1518
|
+
};
|
|
1519
|
+
var generateTagsAsReactComponent = (type, tags) => tags.map((tag, i) => {
|
|
1520
|
+
const mappedTag = {
|
|
1521
|
+
key: i,
|
|
1522
|
+
[HELMET_ATTRIBUTE]: true
|
|
1523
|
+
};
|
|
1524
|
+
Object.keys(tag).forEach((attribute) => {
|
|
1525
|
+
const mapped = REACT_TAG_MAP[attribute];
|
|
1526
|
+
const mappedAttribute = mapped || attribute;
|
|
1527
|
+
if (mappedAttribute === "innerHTML" || mappedAttribute === "cssText") {
|
|
1528
|
+
const content = tag.innerHTML || tag.cssText;
|
|
1529
|
+
mappedTag.dangerouslySetInnerHTML = { __html: content };
|
|
1530
|
+
} else {
|
|
1531
|
+
mappedTag[mappedAttribute] = tag[attribute];
|
|
1532
|
+
}
|
|
1533
|
+
});
|
|
1534
|
+
return import_react3.default.createElement(type, mappedTag);
|
|
1535
|
+
});
|
|
1536
|
+
var getMethodsForTag = (type, tags, encode = true) => {
|
|
1537
|
+
switch (type) {
|
|
1538
|
+
case "title":
|
|
1539
|
+
return {
|
|
1540
|
+
toComponent: () => generateTitleAsReactComponent(type, tags.title, tags.titleAttributes),
|
|
1541
|
+
toString: () => generateTitleAsString(type, tags.title, tags.titleAttributes, encode)
|
|
1542
|
+
};
|
|
1543
|
+
case "bodyAttributes":
|
|
1544
|
+
case "htmlAttributes":
|
|
1545
|
+
return {
|
|
1546
|
+
toComponent: () => convertElementAttributesToReactProps(tags),
|
|
1547
|
+
toString: () => generateElementAttributesAsString(tags)
|
|
1548
|
+
};
|
|
1549
|
+
default:
|
|
1550
|
+
return {
|
|
1551
|
+
toComponent: () => generateTagsAsReactComponent(type, tags),
|
|
1552
|
+
toString: () => generateTagsAsString(type, tags, encode)
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
var getPriorityMethods = ({ metaTags, linkTags, scriptTags, encode }) => {
|
|
1557
|
+
const meta = prioritizer(metaTags, SEO_PRIORITY_TAGS.meta);
|
|
1558
|
+
const link = prioritizer(linkTags, SEO_PRIORITY_TAGS.link);
|
|
1559
|
+
const script = prioritizer(scriptTags, SEO_PRIORITY_TAGS.script);
|
|
1560
|
+
const priorityMethods = {
|
|
1561
|
+
toComponent: () => [
|
|
1562
|
+
...generateTagsAsReactComponent("meta", meta.priority),
|
|
1563
|
+
...generateTagsAsReactComponent("link", link.priority),
|
|
1564
|
+
...generateTagsAsReactComponent("script", script.priority)
|
|
1565
|
+
],
|
|
1566
|
+
toString: () => (
|
|
1567
|
+
// generate all the tags as strings and concatenate them
|
|
1568
|
+
`${getMethodsForTag("meta", meta.priority, encode)} ${getMethodsForTag(
|
|
1569
|
+
"link",
|
|
1570
|
+
link.priority,
|
|
1571
|
+
encode
|
|
1572
|
+
)} ${getMethodsForTag("script", script.priority, encode)}`
|
|
1573
|
+
)
|
|
1574
|
+
};
|
|
1575
|
+
return {
|
|
1576
|
+
priorityMethods,
|
|
1577
|
+
metaTags: meta.default,
|
|
1578
|
+
linkTags: link.default,
|
|
1579
|
+
scriptTags: script.default
|
|
1580
|
+
};
|
|
1581
|
+
};
|
|
1582
|
+
var mapStateOnServer = (props) => {
|
|
1583
|
+
const {
|
|
1584
|
+
baseTag,
|
|
1585
|
+
bodyAttributes,
|
|
1586
|
+
encode = true,
|
|
1587
|
+
htmlAttributes,
|
|
1588
|
+
noscriptTags,
|
|
1589
|
+
styleTags,
|
|
1590
|
+
title = "",
|
|
1591
|
+
titleAttributes,
|
|
1592
|
+
prioritizeSeoTags
|
|
1593
|
+
} = props;
|
|
1594
|
+
let { linkTags, metaTags, scriptTags } = props;
|
|
1595
|
+
let priorityMethods = {
|
|
1596
|
+
toComponent: () => {
|
|
1597
|
+
},
|
|
1598
|
+
toString: () => ""
|
|
1599
|
+
};
|
|
1600
|
+
if (prioritizeSeoTags) {
|
|
1601
|
+
({ priorityMethods, linkTags, metaTags, scriptTags } = getPriorityMethods(props));
|
|
1602
|
+
}
|
|
1603
|
+
return {
|
|
1604
|
+
priority: priorityMethods,
|
|
1605
|
+
base: getMethodsForTag("base", baseTag, encode),
|
|
1606
|
+
bodyAttributes: getMethodsForTag("bodyAttributes", bodyAttributes, encode),
|
|
1607
|
+
htmlAttributes: getMethodsForTag("htmlAttributes", htmlAttributes, encode),
|
|
1608
|
+
link: getMethodsForTag("link", linkTags, encode),
|
|
1609
|
+
meta: getMethodsForTag("meta", metaTags, encode),
|
|
1610
|
+
noscript: getMethodsForTag("noscript", noscriptTags, encode),
|
|
1611
|
+
script: getMethodsForTag("script", scriptTags, encode),
|
|
1612
|
+
style: getMethodsForTag("style", styleTags, encode),
|
|
1613
|
+
title: getMethodsForTag("title", { title, titleAttributes }, encode)
|
|
1614
|
+
};
|
|
1615
|
+
};
|
|
1616
|
+
var server_default = mapStateOnServer;
|
|
1617
|
+
var instances = [];
|
|
1618
|
+
var isDocument = !!(typeof window !== "undefined" && window.document && window.document.createElement);
|
|
1619
|
+
var HelmetData = class {
|
|
1620
|
+
instances = [];
|
|
1621
|
+
canUseDOM = isDocument;
|
|
1622
|
+
context;
|
|
1623
|
+
value = {
|
|
1624
|
+
setHelmet: (serverState) => {
|
|
1625
|
+
this.context.helmet = serverState;
|
|
1626
|
+
},
|
|
1627
|
+
helmetInstances: {
|
|
1628
|
+
get: () => this.canUseDOM ? instances : this.instances,
|
|
1629
|
+
add: (instance) => {
|
|
1630
|
+
(this.canUseDOM ? instances : this.instances).push(instance);
|
|
1631
|
+
},
|
|
1632
|
+
remove: (instance) => {
|
|
1633
|
+
const index = (this.canUseDOM ? instances : this.instances).indexOf(instance);
|
|
1634
|
+
(this.canUseDOM ? instances : this.instances).splice(index, 1);
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
};
|
|
1638
|
+
constructor(context, canUseDOM) {
|
|
1639
|
+
this.context = context;
|
|
1640
|
+
this.canUseDOM = canUseDOM || false;
|
|
1641
|
+
if (!canUseDOM) {
|
|
1642
|
+
context.helmet = server_default({
|
|
1643
|
+
baseTag: [],
|
|
1644
|
+
bodyAttributes: {},
|
|
1645
|
+
encodeSpecialCharacters: true,
|
|
1646
|
+
htmlAttributes: {},
|
|
1647
|
+
linkTags: [],
|
|
1648
|
+
metaTags: [],
|
|
1649
|
+
noscriptTags: [],
|
|
1650
|
+
scriptTags: [],
|
|
1651
|
+
styleTags: [],
|
|
1652
|
+
title: "",
|
|
1653
|
+
titleAttributes: {}
|
|
1654
|
+
});
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1658
|
+
var defaultValue = {};
|
|
1659
|
+
var Context = import_react2.default.createContext(defaultValue);
|
|
1660
|
+
var HelmetProvider = class _HelmetProvider extends import_react2.Component {
|
|
1661
|
+
static canUseDOM = isDocument;
|
|
1662
|
+
helmetData;
|
|
1663
|
+
constructor(props) {
|
|
1664
|
+
super(props);
|
|
1665
|
+
this.helmetData = new HelmetData(this.props.context || {}, _HelmetProvider.canUseDOM);
|
|
1666
|
+
}
|
|
1667
|
+
render() {
|
|
1668
|
+
return /* @__PURE__ */ import_react2.default.createElement(Context.Provider, { value: this.helmetData.value }, this.props.children);
|
|
1669
|
+
}
|
|
1670
|
+
};
|
|
1671
|
+
var updateTags = (type, tags) => {
|
|
1672
|
+
const headElement = document.head || document.querySelector(
|
|
1673
|
+
"head"
|
|
1674
|
+
/* HEAD */
|
|
1675
|
+
);
|
|
1676
|
+
const tagNodes = headElement.querySelectorAll(`${type}[${HELMET_ATTRIBUTE}]`);
|
|
1677
|
+
const oldTags = [].slice.call(tagNodes);
|
|
1678
|
+
const newTags = [];
|
|
1679
|
+
let indexToDelete;
|
|
1680
|
+
if (tags && tags.length) {
|
|
1681
|
+
tags.forEach((tag) => {
|
|
1682
|
+
const newElement = document.createElement(type);
|
|
1683
|
+
for (const attribute in tag) {
|
|
1684
|
+
if (Object.prototype.hasOwnProperty.call(tag, attribute)) {
|
|
1685
|
+
if (attribute === "innerHTML") {
|
|
1686
|
+
newElement.innerHTML = tag.innerHTML;
|
|
1687
|
+
} else if (attribute === "cssText") {
|
|
1688
|
+
if (newElement.styleSheet) {
|
|
1689
|
+
newElement.styleSheet.cssText = tag.cssText;
|
|
1690
|
+
} else {
|
|
1691
|
+
newElement.appendChild(document.createTextNode(tag.cssText));
|
|
1692
|
+
}
|
|
1693
|
+
} else {
|
|
1694
|
+
const attr = attribute;
|
|
1695
|
+
const value = typeof tag[attr] === "undefined" ? "" : tag[attr];
|
|
1696
|
+
newElement.setAttribute(attribute, value);
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
newElement.setAttribute(HELMET_ATTRIBUTE, "true");
|
|
1701
|
+
if (oldTags.some((existingTag, index) => {
|
|
1702
|
+
indexToDelete = index;
|
|
1703
|
+
return newElement.isEqualNode(existingTag);
|
|
1704
|
+
})) {
|
|
1705
|
+
oldTags.splice(indexToDelete, 1);
|
|
1706
|
+
} else {
|
|
1707
|
+
newTags.push(newElement);
|
|
1708
|
+
}
|
|
1709
|
+
});
|
|
1710
|
+
}
|
|
1711
|
+
oldTags.forEach((tag) => tag.parentNode?.removeChild(tag));
|
|
1712
|
+
newTags.forEach((tag) => headElement.appendChild(tag));
|
|
1713
|
+
return {
|
|
1714
|
+
oldTags,
|
|
1715
|
+
newTags
|
|
1716
|
+
};
|
|
1717
|
+
};
|
|
1718
|
+
var updateAttributes = (tagName, attributes) => {
|
|
1719
|
+
const elementTag = document.getElementsByTagName(tagName)[0];
|
|
1720
|
+
if (!elementTag) {
|
|
1721
|
+
return;
|
|
1722
|
+
}
|
|
1723
|
+
const helmetAttributeString = elementTag.getAttribute(HELMET_ATTRIBUTE);
|
|
1724
|
+
const helmetAttributes = helmetAttributeString ? helmetAttributeString.split(",") : [];
|
|
1725
|
+
const attributesToRemove = [...helmetAttributes];
|
|
1726
|
+
const attributeKeys = Object.keys(attributes);
|
|
1727
|
+
for (const attribute of attributeKeys) {
|
|
1728
|
+
const value = attributes[attribute] || "";
|
|
1729
|
+
if (elementTag.getAttribute(attribute) !== value) {
|
|
1730
|
+
elementTag.setAttribute(attribute, value);
|
|
1731
|
+
}
|
|
1732
|
+
if (helmetAttributes.indexOf(attribute) === -1) {
|
|
1733
|
+
helmetAttributes.push(attribute);
|
|
1734
|
+
}
|
|
1735
|
+
const indexToSave = attributesToRemove.indexOf(attribute);
|
|
1736
|
+
if (indexToSave !== -1) {
|
|
1737
|
+
attributesToRemove.splice(indexToSave, 1);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
for (let i = attributesToRemove.length - 1; i >= 0; i -= 1) {
|
|
1741
|
+
elementTag.removeAttribute(attributesToRemove[i]);
|
|
1742
|
+
}
|
|
1743
|
+
if (helmetAttributes.length === attributesToRemove.length) {
|
|
1744
|
+
elementTag.removeAttribute(HELMET_ATTRIBUTE);
|
|
1745
|
+
} else if (elementTag.getAttribute(HELMET_ATTRIBUTE) !== attributeKeys.join(",")) {
|
|
1746
|
+
elementTag.setAttribute(HELMET_ATTRIBUTE, attributeKeys.join(","));
|
|
1747
|
+
}
|
|
1748
|
+
};
|
|
1749
|
+
var updateTitle = (title, attributes) => {
|
|
1750
|
+
if (typeof title !== "undefined" && document.title !== title) {
|
|
1751
|
+
document.title = flattenArray(title);
|
|
1752
|
+
}
|
|
1753
|
+
updateAttributes("title", attributes);
|
|
1754
|
+
};
|
|
1755
|
+
var commitTagChanges = (newState, cb) => {
|
|
1756
|
+
const {
|
|
1757
|
+
baseTag,
|
|
1758
|
+
bodyAttributes,
|
|
1759
|
+
htmlAttributes,
|
|
1760
|
+
linkTags,
|
|
1761
|
+
metaTags,
|
|
1762
|
+
noscriptTags,
|
|
1763
|
+
onChangeClientState,
|
|
1764
|
+
scriptTags,
|
|
1765
|
+
styleTags,
|
|
1766
|
+
title,
|
|
1767
|
+
titleAttributes
|
|
1768
|
+
} = newState;
|
|
1769
|
+
updateAttributes("body", bodyAttributes);
|
|
1770
|
+
updateAttributes("html", htmlAttributes);
|
|
1771
|
+
updateTitle(title, titleAttributes);
|
|
1772
|
+
const tagUpdates = {
|
|
1773
|
+
baseTag: updateTags("base", baseTag),
|
|
1774
|
+
linkTags: updateTags("link", linkTags),
|
|
1775
|
+
metaTags: updateTags("meta", metaTags),
|
|
1776
|
+
noscriptTags: updateTags("noscript", noscriptTags),
|
|
1777
|
+
scriptTags: updateTags("script", scriptTags),
|
|
1778
|
+
styleTags: updateTags("style", styleTags)
|
|
1779
|
+
};
|
|
1780
|
+
const addedTags = {};
|
|
1781
|
+
const removedTags = {};
|
|
1782
|
+
Object.keys(tagUpdates).forEach((tagType) => {
|
|
1783
|
+
const { newTags, oldTags } = tagUpdates[tagType];
|
|
1784
|
+
if (newTags.length) {
|
|
1785
|
+
addedTags[tagType] = newTags;
|
|
1786
|
+
}
|
|
1787
|
+
if (oldTags.length) {
|
|
1788
|
+
removedTags[tagType] = tagUpdates[tagType].oldTags;
|
|
1789
|
+
}
|
|
1790
|
+
});
|
|
1791
|
+
if (cb) {
|
|
1792
|
+
cb();
|
|
1793
|
+
}
|
|
1794
|
+
onChangeClientState(newState, addedTags, removedTags);
|
|
1795
|
+
};
|
|
1796
|
+
var _helmetCallback = null;
|
|
1797
|
+
var handleStateChangeOnClient = (newState) => {
|
|
1798
|
+
if (_helmetCallback) {
|
|
1799
|
+
cancelAnimationFrame(_helmetCallback);
|
|
1800
|
+
}
|
|
1801
|
+
if (newState.defer) {
|
|
1802
|
+
_helmetCallback = requestAnimationFrame(() => {
|
|
1803
|
+
commitTagChanges(newState, () => {
|
|
1804
|
+
_helmetCallback = null;
|
|
1805
|
+
});
|
|
1806
|
+
});
|
|
1807
|
+
} else {
|
|
1808
|
+
commitTagChanges(newState);
|
|
1809
|
+
_helmetCallback = null;
|
|
1810
|
+
}
|
|
1811
|
+
};
|
|
1812
|
+
var client_default = handleStateChangeOnClient;
|
|
1813
|
+
var HelmetDispatcher = class extends import_react4.Component {
|
|
1814
|
+
rendered = false;
|
|
1815
|
+
shouldComponentUpdate(nextProps) {
|
|
1816
|
+
return !(0, import_shallowequal.default)(nextProps, this.props);
|
|
1817
|
+
}
|
|
1818
|
+
componentDidUpdate() {
|
|
1819
|
+
this.emitChange();
|
|
1820
|
+
}
|
|
1821
|
+
componentWillUnmount() {
|
|
1822
|
+
const { helmetInstances } = this.props.context;
|
|
1823
|
+
helmetInstances.remove(this);
|
|
1824
|
+
this.emitChange();
|
|
1825
|
+
}
|
|
1826
|
+
emitChange() {
|
|
1827
|
+
const { helmetInstances, setHelmet } = this.props.context;
|
|
1828
|
+
let serverState = null;
|
|
1829
|
+
const state = reducePropsToState(
|
|
1830
|
+
helmetInstances.get().map((instance) => {
|
|
1831
|
+
const props = { ...instance.props };
|
|
1832
|
+
delete props.context;
|
|
1833
|
+
return props;
|
|
1834
|
+
})
|
|
1835
|
+
);
|
|
1836
|
+
if (HelmetProvider.canUseDOM) {
|
|
1837
|
+
client_default(state);
|
|
1838
|
+
} else if (server_default) {
|
|
1839
|
+
serverState = server_default(state);
|
|
1840
|
+
}
|
|
1841
|
+
setHelmet(serverState);
|
|
1842
|
+
}
|
|
1843
|
+
// componentWillMount will be deprecated
|
|
1844
|
+
// for SSR, initialize on first render
|
|
1845
|
+
// constructor is also unsafe in StrictMode
|
|
1846
|
+
init() {
|
|
1847
|
+
if (this.rendered) {
|
|
1848
|
+
return;
|
|
1849
|
+
}
|
|
1850
|
+
this.rendered = true;
|
|
1851
|
+
const { helmetInstances } = this.props.context;
|
|
1852
|
+
helmetInstances.add(this);
|
|
1853
|
+
this.emitChange();
|
|
1854
|
+
}
|
|
1855
|
+
render() {
|
|
1856
|
+
this.init();
|
|
1857
|
+
return null;
|
|
1858
|
+
}
|
|
1859
|
+
};
|
|
1860
|
+
var Helmet = class extends import_react.Component {
|
|
1861
|
+
static defaultProps = {
|
|
1862
|
+
defer: true,
|
|
1863
|
+
encodeSpecialCharacters: true,
|
|
1864
|
+
prioritizeSeoTags: false
|
|
1865
|
+
};
|
|
1866
|
+
shouldComponentUpdate(nextProps) {
|
|
1867
|
+
return !(0, import_react_fast_compare.default)(without(this.props, "helmetData"), without(nextProps, "helmetData"));
|
|
1868
|
+
}
|
|
1869
|
+
mapNestedChildrenToProps(child, nestedChildren) {
|
|
1870
|
+
if (!nestedChildren) {
|
|
1871
|
+
return null;
|
|
1872
|
+
}
|
|
1873
|
+
switch (child.type) {
|
|
1874
|
+
case "script":
|
|
1875
|
+
case "noscript":
|
|
1876
|
+
return {
|
|
1877
|
+
innerHTML: nestedChildren
|
|
1878
|
+
};
|
|
1879
|
+
case "style":
|
|
1880
|
+
return {
|
|
1881
|
+
cssText: nestedChildren
|
|
1882
|
+
};
|
|
1883
|
+
default:
|
|
1884
|
+
throw new Error(
|
|
1885
|
+
`<${child.type} /> elements are self-closing and can not contain children. Refer to our API for more information.`
|
|
1886
|
+
);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
flattenArrayTypeChildren(child, arrayTypeChildren, newChildProps, nestedChildren) {
|
|
1890
|
+
return {
|
|
1891
|
+
...arrayTypeChildren,
|
|
1892
|
+
[child.type]: [
|
|
1893
|
+
...arrayTypeChildren[child.type] || [],
|
|
1894
|
+
{
|
|
1895
|
+
...newChildProps,
|
|
1896
|
+
...this.mapNestedChildrenToProps(child, nestedChildren)
|
|
1897
|
+
}
|
|
1898
|
+
]
|
|
1899
|
+
};
|
|
1900
|
+
}
|
|
1901
|
+
mapObjectTypeChildren(child, newProps, newChildProps, nestedChildren) {
|
|
1902
|
+
switch (child.type) {
|
|
1903
|
+
case "title":
|
|
1904
|
+
return {
|
|
1905
|
+
...newProps,
|
|
1906
|
+
[child.type]: nestedChildren,
|
|
1907
|
+
titleAttributes: { ...newChildProps }
|
|
1908
|
+
};
|
|
1909
|
+
case "body":
|
|
1910
|
+
return {
|
|
1911
|
+
...newProps,
|
|
1912
|
+
bodyAttributes: { ...newChildProps }
|
|
1913
|
+
};
|
|
1914
|
+
case "html":
|
|
1915
|
+
return {
|
|
1916
|
+
...newProps,
|
|
1917
|
+
htmlAttributes: { ...newChildProps }
|
|
1918
|
+
};
|
|
1919
|
+
default:
|
|
1920
|
+
return {
|
|
1921
|
+
...newProps,
|
|
1922
|
+
[child.type]: { ...newChildProps }
|
|
1923
|
+
};
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
mapArrayTypeChildrenToProps(arrayTypeChildren, newProps) {
|
|
1927
|
+
let newFlattenedProps = { ...newProps };
|
|
1928
|
+
Object.keys(arrayTypeChildren).forEach((arrayChildName) => {
|
|
1929
|
+
newFlattenedProps = {
|
|
1930
|
+
...newFlattenedProps,
|
|
1931
|
+
[arrayChildName]: arrayTypeChildren[arrayChildName]
|
|
1932
|
+
};
|
|
1933
|
+
});
|
|
1934
|
+
return newFlattenedProps;
|
|
1935
|
+
}
|
|
1936
|
+
warnOnInvalidChildren(child, nestedChildren) {
|
|
1937
|
+
(0, import_invariant.default)(
|
|
1938
|
+
VALID_TAG_NAMES.some((name) => child.type === name),
|
|
1939
|
+
typeof child.type === "function" ? `You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.` : `Only elements types ${VALID_TAG_NAMES.join(
|
|
1940
|
+
", "
|
|
1941
|
+
)} are allowed. Helmet does not support rendering <${child.type}> elements. Refer to our API for more information.`
|
|
1942
|
+
);
|
|
1943
|
+
(0, import_invariant.default)(
|
|
1944
|
+
!nestedChildren || typeof nestedChildren === "string" || Array.isArray(nestedChildren) && !nestedChildren.some((nestedChild) => typeof nestedChild !== "string"),
|
|
1945
|
+
`Helmet expects a string as a child of <${child.type}>. Did you forget to wrap your children in braces? ( <${child.type}>{\`\`}</${child.type}> ) Refer to our API for more information.`
|
|
1946
|
+
);
|
|
1947
|
+
return true;
|
|
1948
|
+
}
|
|
1949
|
+
mapChildrenToProps(children, newProps) {
|
|
1950
|
+
let arrayTypeChildren = {};
|
|
1951
|
+
import_react.default.Children.forEach(children, (child) => {
|
|
1952
|
+
if (!child || !child.props) {
|
|
1953
|
+
return;
|
|
1954
|
+
}
|
|
1955
|
+
const { children: nestedChildren, ...childProps } = child.props;
|
|
1956
|
+
const newChildProps = Object.keys(childProps).reduce((obj, key) => {
|
|
1957
|
+
obj[HTML_TAG_MAP[key] || key] = childProps[key];
|
|
1958
|
+
return obj;
|
|
1959
|
+
}, {});
|
|
1960
|
+
let { type } = child;
|
|
1961
|
+
if (typeof type === "symbol") {
|
|
1962
|
+
type = type.toString();
|
|
1963
|
+
} else {
|
|
1964
|
+
this.warnOnInvalidChildren(child, nestedChildren);
|
|
1965
|
+
}
|
|
1966
|
+
switch (type) {
|
|
1967
|
+
case "Symbol(react.fragment)":
|
|
1968
|
+
newProps = this.mapChildrenToProps(nestedChildren, newProps);
|
|
1969
|
+
break;
|
|
1970
|
+
case "link":
|
|
1971
|
+
case "meta":
|
|
1972
|
+
case "noscript":
|
|
1973
|
+
case "script":
|
|
1974
|
+
case "style":
|
|
1975
|
+
arrayTypeChildren = this.flattenArrayTypeChildren(
|
|
1976
|
+
child,
|
|
1977
|
+
arrayTypeChildren,
|
|
1978
|
+
newChildProps,
|
|
1979
|
+
nestedChildren
|
|
1980
|
+
);
|
|
1981
|
+
break;
|
|
1982
|
+
default:
|
|
1983
|
+
newProps = this.mapObjectTypeChildren(child, newProps, newChildProps, nestedChildren);
|
|
1984
|
+
break;
|
|
1985
|
+
}
|
|
1986
|
+
});
|
|
1987
|
+
return this.mapArrayTypeChildrenToProps(arrayTypeChildren, newProps);
|
|
1988
|
+
}
|
|
1989
|
+
render() {
|
|
1990
|
+
const { children, ...props } = this.props;
|
|
1991
|
+
let newProps = { ...props };
|
|
1992
|
+
let { helmetData } = props;
|
|
1993
|
+
if (children) {
|
|
1994
|
+
newProps = this.mapChildrenToProps(children, newProps);
|
|
1995
|
+
}
|
|
1996
|
+
if (helmetData && !(helmetData instanceof HelmetData)) {
|
|
1997
|
+
const data = helmetData;
|
|
1998
|
+
helmetData = new HelmetData(data.context, true);
|
|
1999
|
+
delete newProps.helmetData;
|
|
2000
|
+
}
|
|
2001
|
+
return helmetData ? /* @__PURE__ */ import_react.default.createElement(HelmetDispatcher, { ...newProps, context: helmetData.value }) : /* @__PURE__ */ import_react.default.createElement(Context.Consumer, null, (context) => /* @__PURE__ */ import_react.default.createElement(HelmetDispatcher, { ...newProps, context }));
|
|
2002
|
+
}
|
|
2003
|
+
};
|
|
2004
|
+
|
|
2005
|
+
// src/components/SEOProvider.tsx
|
|
2006
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
2007
|
+
var SEOContext = (0, import_react5.createContext)(void 0);
|
|
404
2008
|
var SEOProvider = ({ config, children, helmetContext }) => {
|
|
405
|
-
return /* @__PURE__ */ (0,
|
|
2009
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SEOContext.Provider, { value: { config }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(HelmetProvider, { context: helmetContext, children }) });
|
|
406
2010
|
};
|
|
407
2011
|
var useSEOConfig = () => {
|
|
408
|
-
const context = (0,
|
|
2012
|
+
const context = (0, import_react5.useContext)(SEOContext);
|
|
409
2013
|
if (!context) {
|
|
410
2014
|
throw new Error("useSEOConfig must be used within an SEOProvider");
|
|
411
2015
|
}
|
|
@@ -413,8 +2017,7 @@ var useSEOConfig = () => {
|
|
|
413
2017
|
};
|
|
414
2018
|
|
|
415
2019
|
// src/components/SEO.tsx
|
|
416
|
-
var
|
|
417
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
2020
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
418
2021
|
var SEO = (props) => {
|
|
419
2022
|
const config = useSEOConfig();
|
|
420
2023
|
const title = props.title ? `${props.title} | ${config.name}` : config.name;
|
|
@@ -493,57 +2096,56 @@ var SEO = (props) => {
|
|
|
493
2096
|
schemas.push(props.schema);
|
|
494
2097
|
}
|
|
495
2098
|
}
|
|
496
|
-
return /* @__PURE__ */ (0,
|
|
497
|
-
/* @__PURE__ */ (0,
|
|
498
|
-
/* @__PURE__ */ (0,
|
|
499
|
-
props.keywords && /* @__PURE__ */ (0,
|
|
500
|
-
/* @__PURE__ */ (0,
|
|
501
|
-
!props.noindex && /* @__PURE__ */ (0,
|
|
502
|
-
props.prev && /* @__PURE__ */ (0,
|
|
503
|
-
props.next && /* @__PURE__ */ (0,
|
|
504
|
-
config.language && /* @__PURE__ */ (0,
|
|
505
|
-
props.alternates?.map((alt, i) => /* @__PURE__ */ (0,
|
|
506
|
-
/* @__PURE__ */ (0,
|
|
507
|
-
/* @__PURE__ */ (0,
|
|
508
|
-
/* @__PURE__ */ (0,
|
|
509
|
-
/* @__PURE__ */ (0,
|
|
510
|
-
/* @__PURE__ */ (0,
|
|
511
|
-
/* @__PURE__ */ (0,
|
|
512
|
-
/* @__PURE__ */ (0,
|
|
513
|
-
config.facebookAppId && /* @__PURE__ */ (0,
|
|
514
|
-
/* @__PURE__ */ (0,
|
|
515
|
-
/* @__PURE__ */ (0,
|
|
516
|
-
/* @__PURE__ */ (0,
|
|
517
|
-
/* @__PURE__ */ (0,
|
|
518
|
-
config.twitterHandle && /* @__PURE__ */ (0,
|
|
519
|
-
config.twitterHandle && /* @__PURE__ */ (0,
|
|
520
|
-
props.readingTime && /* @__PURE__ */ (0,
|
|
521
|
-
props.readingTime && /* @__PURE__ */ (0,
|
|
522
|
-
props.type === "article" && props.publishedTime && /* @__PURE__ */ (0,
|
|
523
|
-
props.type === "article" && props.modifiedTime && /* @__PURE__ */ (0,
|
|
524
|
-
props.type === "article" && props.section && /* @__PURE__ */ (0,
|
|
525
|
-
props.type === "article" && props.tags?.map((tag) => /* @__PURE__ */ (0,
|
|
526
|
-
config.themeColor && /* @__PURE__ */ (0,
|
|
527
|
-
config.manifest && /* @__PURE__ */ (0,
|
|
528
|
-
/* @__PURE__ */ (0,
|
|
529
|
-
/* @__PURE__ */ (0,
|
|
530
|
-
/* @__PURE__ */ (0,
|
|
531
|
-
props.dnsPrefetch?.map((d) => /* @__PURE__ */ (0,
|
|
532
|
-
props.preconnect?.map((d) => /* @__PURE__ */ (0,
|
|
533
|
-
props.prefetch?.map((d) => /* @__PURE__ */ (0,
|
|
534
|
-
props.preload?.map((p) => /* @__PURE__ */ (0,
|
|
535
|
-
(props.whatsappImage || image) && /* @__PURE__ */ (0,
|
|
536
|
-
props.whatsappDescription && /* @__PURE__ */ (0,
|
|
537
|
-
config.googleAnalyticsId && /* @__PURE__ */ (0,
|
|
538
|
-
config.googleAnalyticsId && /* @__PURE__ */ (0,
|
|
539
|
-
schemas.map((schema, index) => /* @__PURE__ */ (0,
|
|
2099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Helmet, { children: [
|
|
2100
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("title", { children: title }),
|
|
2101
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "description", content: description }),
|
|
2102
|
+
props.keywords && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "keywords", content: props.keywords.join(", ") }),
|
|
2103
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "robots", content: props.noindex ? "noindex, nofollow" : props.robots || "index, follow" }),
|
|
2104
|
+
!props.noindex && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "canonical", href: url }),
|
|
2105
|
+
props.prev && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "prev", href: props.prev }),
|
|
2106
|
+
props.next && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "next", href: props.next }),
|
|
2107
|
+
config.language && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { httpEquiv: "content-language", content: config.language }),
|
|
2108
|
+
props.alternates?.map((alt, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "alternate", hrefLang: alt.hreflang, href: alt.href }, i)),
|
|
2109
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:type", content: props.ogType || (props.type === "article" ? "article" : "website") }),
|
|
2110
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:title", content: props.ogTitle || title }),
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:description", content: props.ogDescription || description }),
|
|
2112
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:image", content: props.ogImage || image }),
|
|
2113
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:url", content: url }),
|
|
2114
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:site_name", content: config.name }),
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:locale", content: props.ogLocale || config.language || "en_US" }),
|
|
2116
|
+
config.facebookAppId && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "fb:app_id", content: config.facebookAppId }),
|
|
2117
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:card", content: props.twitterCard || "summary_large_image" }),
|
|
2118
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:title", content: props.twitterTitle || title }),
|
|
2119
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:description", content: props.twitterDescription || description }),
|
|
2120
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:image", content: props.twitterImage || image }),
|
|
2121
|
+
config.twitterHandle && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:site", content: config.twitterHandle }),
|
|
2122
|
+
config.twitterHandle && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:creator", content: config.twitterHandle }),
|
|
2123
|
+
props.readingTime && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:label1", content: "Reading time" }),
|
|
2124
|
+
props.readingTime && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:data1", content: `${props.readingTime} min` }),
|
|
2125
|
+
props.type === "article" && props.publishedTime && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "article:published_time", content: props.publishedTime }),
|
|
2126
|
+
props.type === "article" && props.modifiedTime && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "article:modified_time", content: props.modifiedTime }),
|
|
2127
|
+
props.type === "article" && props.section && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "article:section", content: props.section }),
|
|
2128
|
+
props.type === "article" && props.tags?.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "article:tag", content: tag }, tag)),
|
|
2129
|
+
config.themeColor && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "theme-color", content: config.themeColor }),
|
|
2130
|
+
config.manifest && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "manifest", href: config.manifest }),
|
|
2131
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "apple-mobile-web-app-capable", content: "yes" }),
|
|
2132
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "apple-mobile-web-app-status-bar-style", content: "default" }),
|
|
2133
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "apple-mobile-web-app-title", content: config.name }),
|
|
2134
|
+
props.dnsPrefetch?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "dns-prefetch", href: d }, d)),
|
|
2135
|
+
props.preconnect?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "preconnect", href: d }, d)),
|
|
2136
|
+
props.prefetch?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "prefetch", href: d }, d)),
|
|
2137
|
+
props.preload?.map((p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "preload", href: p.href, as: p.as, type: p.type }, p.href)),
|
|
2138
|
+
(props.whatsappImage || image) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:image:secure_url", content: props.whatsappImage || image }),
|
|
2139
|
+
props.whatsappDescription && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "whatsapp:description", content: props.whatsappDescription }),
|
|
2140
|
+
config.googleAnalyticsId && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("script", { async: true, src: `https://www.googletagmanager.com/gtag/js?id=${config.googleAnalyticsId}` }),
|
|
2141
|
+
config.googleAnalyticsId && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("script", { children: `window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '${config.googleAnalyticsId}');` }),
|
|
2142
|
+
schemas.map((schema, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }, index)),
|
|
540
2143
|
props.children
|
|
541
2144
|
] });
|
|
542
2145
|
};
|
|
543
2146
|
|
|
544
2147
|
// src/components/Breadcrumb.tsx
|
|
545
|
-
var
|
|
546
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
2148
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
547
2149
|
var Breadcrumb = ({
|
|
548
2150
|
items,
|
|
549
2151
|
className = "breadcrumb",
|
|
@@ -560,22 +2162,22 @@ var Breadcrumb = ({
|
|
|
560
2162
|
"item": item.item
|
|
561
2163
|
}))
|
|
562
2164
|
};
|
|
563
|
-
return /* @__PURE__ */ (0,
|
|
564
|
-
/* @__PURE__ */ (0,
|
|
565
|
-
/* @__PURE__ */ (0,
|
|
2165
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
2166
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) }),
|
|
2167
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("nav", { className, "aria-label": "Breadcrumb", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ol", { style: { display: "flex", listStyle: "none", padding: 0 }, children: items.map((item, index) => {
|
|
566
2168
|
const isLast = index === items.length - 1;
|
|
567
|
-
return /* @__PURE__ */ (0,
|
|
568
|
-
renderLink ? renderLink(item, isLast) : isLast ? /* @__PURE__ */ (0,
|
|
569
|
-
!isLast && /* @__PURE__ */ (0,
|
|
2169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { style: { display: "flex", alignItems: "center" }, children: [
|
|
2170
|
+
renderLink ? renderLink(item, isLast) : isLast ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "aria-current": "page", children: item.name }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: item.item, children: item.name }),
|
|
2171
|
+
!isLast && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { margin: "0 8px" }, children: separator })
|
|
570
2172
|
] }, index);
|
|
571
2173
|
}) }) })
|
|
572
2174
|
] });
|
|
573
2175
|
};
|
|
574
2176
|
|
|
575
2177
|
// src/components/SeoArticle.tsx
|
|
576
|
-
var
|
|
2178
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
577
2179
|
var SeoArticle = ({ article, ...rest }) => {
|
|
578
|
-
return /* @__PURE__ */ (0,
|
|
2180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
579
2181
|
SEO,
|
|
580
2182
|
{
|
|
581
2183
|
type: "article",
|
|
@@ -593,9 +2195,9 @@ var SeoArticle = ({ article, ...rest }) => {
|
|
|
593
2195
|
};
|
|
594
2196
|
|
|
595
2197
|
// src/components/SeoProduct.tsx
|
|
596
|
-
var
|
|
2198
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
597
2199
|
var SeoProduct = ({ item, ...rest }) => {
|
|
598
|
-
return /* @__PURE__ */ (0,
|
|
2200
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
599
2201
|
SEO,
|
|
600
2202
|
{
|
|
601
2203
|
type: "product",
|
|
@@ -617,8 +2219,7 @@ var SeoProduct = ({ item, ...rest }) => {
|
|
|
617
2219
|
};
|
|
618
2220
|
|
|
619
2221
|
// src/components/SeoFAQ.tsx
|
|
620
|
-
var
|
|
621
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2222
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
622
2223
|
var SeoFAQ = ({ items }) => {
|
|
623
2224
|
const schema = {
|
|
624
2225
|
"@context": "https://schema.org",
|
|
@@ -632,12 +2233,11 @@ var SeoFAQ = ({ items }) => {
|
|
|
632
2233
|
}
|
|
633
2234
|
}))
|
|
634
2235
|
};
|
|
635
|
-
return /* @__PURE__ */ (0,
|
|
2236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
636
2237
|
};
|
|
637
2238
|
|
|
638
2239
|
// src/components/SeoVideo.tsx
|
|
639
|
-
var
|
|
640
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2240
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
641
2241
|
var SeoVideo = ({ video }) => {
|
|
642
2242
|
const schema = {
|
|
643
2243
|
"@context": "https://schema.org",
|
|
@@ -655,12 +2255,11 @@ var SeoVideo = ({ video }) => {
|
|
|
655
2255
|
"userInteractionCount": video.interactionStatistic.viewCount
|
|
656
2256
|
} : void 0
|
|
657
2257
|
};
|
|
658
|
-
return /* @__PURE__ */ (0,
|
|
2258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
659
2259
|
};
|
|
660
2260
|
|
|
661
2261
|
// src/components/SeoEvent.tsx
|
|
662
|
-
var
|
|
663
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2262
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
664
2263
|
var SeoEvent = ({ event }) => {
|
|
665
2264
|
const schema = {
|
|
666
2265
|
"@context": "https://schema.org",
|
|
@@ -696,12 +2295,11 @@ var SeoEvent = ({ event }) => {
|
|
|
696
2295
|
"url": event.organizer.url
|
|
697
2296
|
} : void 0
|
|
698
2297
|
};
|
|
699
|
-
return /* @__PURE__ */ (0,
|
|
2298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
700
2299
|
};
|
|
701
2300
|
|
|
702
2301
|
// src/components/SeoLocalBusiness.tsx
|
|
703
|
-
var
|
|
704
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2302
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
705
2303
|
var SeoLocalBusiness = ({ business }) => {
|
|
706
2304
|
const schema = {
|
|
707
2305
|
"@context": "https://schema.org",
|
|
@@ -728,23 +2326,29 @@ var SeoLocalBusiness = ({ business }) => {
|
|
|
728
2326
|
} : void 0,
|
|
729
2327
|
"openingHours": business.openingHours
|
|
730
2328
|
};
|
|
731
|
-
return /* @__PURE__ */ (0,
|
|
2329
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
732
2330
|
};
|
|
733
2331
|
|
|
734
2332
|
// src/components/SeoCategory.tsx
|
|
735
|
-
var
|
|
736
|
-
var SeoCategory = ({
|
|
2333
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2334
|
+
var SeoCategory = ({
|
|
2335
|
+
category,
|
|
2336
|
+
page = 1,
|
|
2337
|
+
totalPage = 1,
|
|
2338
|
+
pageSuffix = "Page",
|
|
2339
|
+
...rest
|
|
2340
|
+
}) => {
|
|
737
2341
|
const hasNext = page < totalPage;
|
|
738
2342
|
const hasPrev = page > 1;
|
|
739
2343
|
const baseUrl = category.url.split("?")[0];
|
|
740
2344
|
const nextUrl = hasNext ? `${baseUrl}?page=${page + 1}` : void 0;
|
|
741
2345
|
const prevUrl = hasPrev ? page === 2 ? baseUrl : `${baseUrl}?page=${page - 1}` : void 0;
|
|
742
2346
|
const canonical = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
|
|
743
|
-
return /* @__PURE__ */ (0,
|
|
2347
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
744
2348
|
SEO,
|
|
745
2349
|
{
|
|
746
2350
|
type: "website",
|
|
747
|
-
title: `${category.name}${page > 1 ? ` -
|
|
2351
|
+
title: `${category.name}${page > 1 ? ` - ${pageSuffix} ${page}` : ""}`,
|
|
748
2352
|
description: category.description,
|
|
749
2353
|
image: category.image,
|
|
750
2354
|
canonical,
|
|
@@ -763,20 +2367,29 @@ var SeoCategory = ({ category, page = 1, totalPage = 1, ...rest }) => {
|
|
|
763
2367
|
};
|
|
764
2368
|
|
|
765
2369
|
// src/components/SeoTag.tsx
|
|
766
|
-
var
|
|
767
|
-
var SeoTag = ({
|
|
2370
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2371
|
+
var SeoTag = ({
|
|
2372
|
+
tag,
|
|
2373
|
+
page = 1,
|
|
2374
|
+
totalPage = 1,
|
|
2375
|
+
titlePrefix = "Tag",
|
|
2376
|
+
pageSuffix = "Page",
|
|
2377
|
+
defaultDescription,
|
|
2378
|
+
...rest
|
|
2379
|
+
}) => {
|
|
768
2380
|
const hasNext = page < totalPage;
|
|
769
2381
|
const hasPrev = page > 1;
|
|
770
2382
|
const baseUrl = tag.url.split("?")[0];
|
|
771
2383
|
const nextUrl = hasNext ? `${baseUrl}?page=${page + 1}` : void 0;
|
|
772
2384
|
const prevUrl = hasPrev ? page === 2 ? baseUrl : `${baseUrl}?page=${page - 1}` : void 0;
|
|
773
2385
|
const canonical = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
|
|
774
|
-
|
|
2386
|
+
const desc = tag.description || (defaultDescription ? defaultDescription.replace("{name}", tag.name) : `All posts tagged with ${tag.name}`);
|
|
2387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
775
2388
|
SEO,
|
|
776
2389
|
{
|
|
777
2390
|
type: "website",
|
|
778
|
-
title:
|
|
779
|
-
description:
|
|
2391
|
+
title: `${titlePrefix}: ${tag.name}${page > 1 ? ` - ${pageSuffix} ${page}` : ""}`,
|
|
2392
|
+
description: desc,
|
|
780
2393
|
canonical,
|
|
781
2394
|
next: nextUrl,
|
|
782
2395
|
prev: prevUrl,
|
|
@@ -786,19 +2399,25 @@ var SeoTag = ({ tag, page = 1, totalPage = 1, ...rest }) => {
|
|
|
786
2399
|
};
|
|
787
2400
|
|
|
788
2401
|
// src/components/SeoAuthor.tsx
|
|
789
|
-
var
|
|
790
|
-
var SeoAuthor = ({
|
|
2402
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2403
|
+
var SeoAuthor = ({
|
|
2404
|
+
author,
|
|
2405
|
+
page = 1,
|
|
2406
|
+
totalPage = 1,
|
|
2407
|
+
pageSuffix = "Page",
|
|
2408
|
+
...rest
|
|
2409
|
+
}) => {
|
|
791
2410
|
const hasNext = page < totalPage;
|
|
792
2411
|
const hasPrev = page > 1;
|
|
793
2412
|
const baseUrl = author.url.split("?")[0];
|
|
794
2413
|
const nextUrl = hasNext ? `${baseUrl}?page=${page + 1}` : void 0;
|
|
795
2414
|
const prevUrl = hasPrev ? page === 2 ? baseUrl : `${baseUrl}?page=${page - 1}` : void 0;
|
|
796
2415
|
const canonical = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
|
|
797
|
-
return /* @__PURE__ */ (0,
|
|
2416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
798
2417
|
SEO,
|
|
799
2418
|
{
|
|
800
2419
|
type: "profile",
|
|
801
|
-
title: `${author.name}${page > 1 ? ` -
|
|
2420
|
+
title: `${author.name}${page > 1 ? ` - ${pageSuffix} ${page}` : ""}`,
|
|
802
2421
|
description: author.description,
|
|
803
2422
|
image: author.image,
|
|
804
2423
|
canonical,
|
|
@@ -819,8 +2438,7 @@ var SeoAuthor = ({ author, page = 1, totalPage = 1, ...rest }) => {
|
|
|
819
2438
|
};
|
|
820
2439
|
|
|
821
2440
|
// src/components/SeoHowTo.tsx
|
|
822
|
-
var
|
|
823
|
-
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2441
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
824
2442
|
var SeoHowTo = ({ name, description, image, steps }) => {
|
|
825
2443
|
const schema = {
|
|
826
2444
|
"@context": "https://schema.org",
|
|
@@ -846,12 +2464,11 @@ var SeoHowTo = ({ name, description, image, steps }) => {
|
|
|
846
2464
|
};
|
|
847
2465
|
})
|
|
848
2466
|
};
|
|
849
|
-
return /* @__PURE__ */ (0,
|
|
2467
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
850
2468
|
};
|
|
851
2469
|
|
|
852
2470
|
// src/components/SeoReview.tsx
|
|
853
|
-
var
|
|
854
|
-
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2471
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
855
2472
|
var SeoReview = ({ itemReviewed, review }) => {
|
|
856
2473
|
const schema = {
|
|
857
2474
|
"@context": "https://schema.org",
|
|
@@ -874,12 +2491,11 @@ var SeoReview = ({ itemReviewed, review }) => {
|
|
|
874
2491
|
"worstRating": review.worstRating || 1
|
|
875
2492
|
}
|
|
876
2493
|
};
|
|
877
|
-
return /* @__PURE__ */ (0,
|
|
2494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
878
2495
|
};
|
|
879
2496
|
|
|
880
2497
|
// src/components/SeoCourse.tsx
|
|
881
|
-
var
|
|
882
|
-
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2498
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
883
2499
|
var SeoCourse = ({ course }) => {
|
|
884
2500
|
const schema = {
|
|
885
2501
|
"@context": "https://schema.org",
|
|
@@ -893,12 +2509,11 @@ var SeoCourse = ({ course }) => {
|
|
|
893
2509
|
},
|
|
894
2510
|
"image": course.image
|
|
895
2511
|
};
|
|
896
|
-
return /* @__PURE__ */ (0,
|
|
2512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
897
2513
|
};
|
|
898
2514
|
|
|
899
2515
|
// src/components/SeoRecipe.tsx
|
|
900
|
-
var
|
|
901
|
-
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2516
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
902
2517
|
var SeoRecipe = ({ recipe }) => {
|
|
903
2518
|
const schema = {
|
|
904
2519
|
"@context": "https://schema.org",
|
|
@@ -925,12 +2540,11 @@ var SeoRecipe = ({ recipe }) => {
|
|
|
925
2540
|
"image": step.image
|
|
926
2541
|
}))
|
|
927
2542
|
};
|
|
928
|
-
return /* @__PURE__ */ (0,
|
|
2543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
929
2544
|
};
|
|
930
2545
|
|
|
931
2546
|
// src/components/SeoJobPosting.tsx
|
|
932
|
-
var
|
|
933
|
-
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2547
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
934
2548
|
var SeoJobPosting = ({ job }) => {
|
|
935
2549
|
const schema = {
|
|
936
2550
|
"@context": "https://schema.org",
|
|
@@ -972,11 +2586,12 @@ var SeoJobPosting = ({ job }) => {
|
|
|
972
2586
|
}
|
|
973
2587
|
} : void 0
|
|
974
2588
|
};
|
|
975
|
-
return /* @__PURE__ */ (0,
|
|
2589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
976
2590
|
};
|
|
977
2591
|
// Annotate the CommonJS export names for ESM import in node:
|
|
978
2592
|
0 && (module.exports = {
|
|
979
2593
|
Breadcrumb,
|
|
2594
|
+
JsonLd,
|
|
980
2595
|
SEO,
|
|
981
2596
|
SEOProvider,
|
|
982
2597
|
SeoArticle,
|
|
@@ -993,11 +2608,19 @@ var SeoJobPosting = ({ job }) => {
|
|
|
993
2608
|
SeoReview,
|
|
994
2609
|
SeoTag,
|
|
995
2610
|
SeoVideo,
|
|
2611
|
+
cleanSchema,
|
|
2612
|
+
generateArticleMetadata,
|
|
996
2613
|
generateArticleSchema,
|
|
997
2614
|
generateBookSchema,
|
|
998
2615
|
generateBreadcrumbSchema,
|
|
2616
|
+
generateCategoryMetadata,
|
|
2617
|
+
generateCollectionPageSchema,
|
|
999
2618
|
generateEventSchema,
|
|
1000
2619
|
generateFAQSchema,
|
|
2620
|
+
generateHomepageMetadata,
|
|
2621
|
+
generateHowToSchema,
|
|
2622
|
+
generateItemListSchema,
|
|
2623
|
+
generateJobPostingSchema,
|
|
1001
2624
|
generateLocalBusinessSchema,
|
|
1002
2625
|
generateMovieSchema,
|
|
1003
2626
|
generateOrganizationSchema,
|
|
@@ -1005,10 +2628,14 @@ var SeoJobPosting = ({ job }) => {
|
|
|
1005
2628
|
generatePaginationLinks,
|
|
1006
2629
|
generatePodcastEpisodeSchema,
|
|
1007
2630
|
generatePodcastSchema,
|
|
2631
|
+
generateProductMetadata,
|
|
1008
2632
|
generateProductSchema,
|
|
2633
|
+
generateRecipeSchema,
|
|
1009
2634
|
generateSoftwareSchema,
|
|
1010
2635
|
generateVideoSchema,
|
|
2636
|
+
generateWebPageSchema,
|
|
1011
2637
|
generateWebSiteSchema,
|
|
1012
2638
|
toNextMetadata,
|
|
1013
|
-
useSEOConfig
|
|
2639
|
+
useSEOConfig,
|
|
2640
|
+
validateSEO
|
|
1014
2641
|
});
|