@masters-ws/react-seo 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +138 -0
- package/dist/index.d.mts +351 -0
- package/dist/index.d.ts +351 -0
- package/dist/index.js +1657 -0
- package/dist/index.mjs +1625 -0
- package/package.json +41 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1657 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
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
|
+
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
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
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
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
|
+
|
|
184
|
+
// src/index.ts
|
|
185
|
+
var index_exports = {};
|
|
186
|
+
__export(index_exports, {
|
|
187
|
+
Breadcrumb: () => Breadcrumb,
|
|
188
|
+
SEO: () => SEO,
|
|
189
|
+
SEOProvider: () => SEOProvider,
|
|
190
|
+
SeoArticle: () => SeoArticle,
|
|
191
|
+
SeoAuthor: () => SeoAuthor,
|
|
192
|
+
SeoCategory: () => SeoCategory,
|
|
193
|
+
SeoCourse: () => SeoCourse,
|
|
194
|
+
SeoEvent: () => SeoEvent,
|
|
195
|
+
SeoFAQ: () => SeoFAQ,
|
|
196
|
+
SeoHowTo: () => SeoHowTo,
|
|
197
|
+
SeoJobPosting: () => SeoJobPosting,
|
|
198
|
+
SeoLocalBusiness: () => SeoLocalBusiness,
|
|
199
|
+
SeoProduct: () => SeoProduct,
|
|
200
|
+
SeoRecipe: () => SeoRecipe,
|
|
201
|
+
SeoReview: () => SeoReview,
|
|
202
|
+
SeoTag: () => SeoTag,
|
|
203
|
+
SeoVideo: () => SeoVideo,
|
|
204
|
+
toNextMetadata: () => toNextMetadata,
|
|
205
|
+
useSEOConfig: () => useSEOConfig
|
|
206
|
+
});
|
|
207
|
+
module.exports = __toCommonJS(index_exports);
|
|
208
|
+
|
|
209
|
+
// src/components/SEOProvider.tsx
|
|
210
|
+
var import_react5 = require("react");
|
|
211
|
+
|
|
212
|
+
// node_modules/react-helmet-async/lib/index.esm.js
|
|
213
|
+
var import_react = __toESM(require("react"));
|
|
214
|
+
var import_react_fast_compare = __toESM(require_react_fast_compare());
|
|
215
|
+
var import_invariant = __toESM(require_invariant());
|
|
216
|
+
var import_react2 = __toESM(require("react"));
|
|
217
|
+
var import_react3 = __toESM(require("react"));
|
|
218
|
+
var import_react4 = require("react");
|
|
219
|
+
var import_shallowequal = __toESM(require_shallowequal());
|
|
220
|
+
var TAG_NAMES = /* @__PURE__ */ ((TAG_NAMES2) => {
|
|
221
|
+
TAG_NAMES2["BASE"] = "base";
|
|
222
|
+
TAG_NAMES2["BODY"] = "body";
|
|
223
|
+
TAG_NAMES2["HEAD"] = "head";
|
|
224
|
+
TAG_NAMES2["HTML"] = "html";
|
|
225
|
+
TAG_NAMES2["LINK"] = "link";
|
|
226
|
+
TAG_NAMES2["META"] = "meta";
|
|
227
|
+
TAG_NAMES2["NOSCRIPT"] = "noscript";
|
|
228
|
+
TAG_NAMES2["SCRIPT"] = "script";
|
|
229
|
+
TAG_NAMES2["STYLE"] = "style";
|
|
230
|
+
TAG_NAMES2["TITLE"] = "title";
|
|
231
|
+
TAG_NAMES2["FRAGMENT"] = "Symbol(react.fragment)";
|
|
232
|
+
return TAG_NAMES2;
|
|
233
|
+
})(TAG_NAMES || {});
|
|
234
|
+
var SEO_PRIORITY_TAGS = {
|
|
235
|
+
link: { rel: ["amphtml", "canonical", "alternate"] },
|
|
236
|
+
script: { type: ["application/ld+json"] },
|
|
237
|
+
meta: {
|
|
238
|
+
charset: "",
|
|
239
|
+
name: ["generator", "robots", "description"],
|
|
240
|
+
property: [
|
|
241
|
+
"og:type",
|
|
242
|
+
"og:title",
|
|
243
|
+
"og:url",
|
|
244
|
+
"og:image",
|
|
245
|
+
"og:image:alt",
|
|
246
|
+
"og:description",
|
|
247
|
+
"twitter:url",
|
|
248
|
+
"twitter:title",
|
|
249
|
+
"twitter:description",
|
|
250
|
+
"twitter:image",
|
|
251
|
+
"twitter:image:alt",
|
|
252
|
+
"twitter:card",
|
|
253
|
+
"twitter:site"
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
var VALID_TAG_NAMES = Object.values(TAG_NAMES);
|
|
258
|
+
var REACT_TAG_MAP = {
|
|
259
|
+
accesskey: "accessKey",
|
|
260
|
+
charset: "charSet",
|
|
261
|
+
class: "className",
|
|
262
|
+
contenteditable: "contentEditable",
|
|
263
|
+
contextmenu: "contextMenu",
|
|
264
|
+
"http-equiv": "httpEquiv",
|
|
265
|
+
itemprop: "itemProp",
|
|
266
|
+
tabindex: "tabIndex"
|
|
267
|
+
};
|
|
268
|
+
var HTML_TAG_MAP = Object.entries(REACT_TAG_MAP).reduce(
|
|
269
|
+
(carry, [key, value]) => {
|
|
270
|
+
carry[value] = key;
|
|
271
|
+
return carry;
|
|
272
|
+
},
|
|
273
|
+
{}
|
|
274
|
+
);
|
|
275
|
+
var HELMET_ATTRIBUTE = "data-rh";
|
|
276
|
+
var HELMET_PROPS = {
|
|
277
|
+
DEFAULT_TITLE: "defaultTitle",
|
|
278
|
+
DEFER: "defer",
|
|
279
|
+
ENCODE_SPECIAL_CHARACTERS: "encodeSpecialCharacters",
|
|
280
|
+
ON_CHANGE_CLIENT_STATE: "onChangeClientState",
|
|
281
|
+
TITLE_TEMPLATE: "titleTemplate",
|
|
282
|
+
PRIORITIZE_SEO_TAGS: "prioritizeSeoTags"
|
|
283
|
+
};
|
|
284
|
+
var getInnermostProperty = (propsList, property) => {
|
|
285
|
+
for (let i = propsList.length - 1; i >= 0; i -= 1) {
|
|
286
|
+
const props = propsList[i];
|
|
287
|
+
if (Object.prototype.hasOwnProperty.call(props, property)) {
|
|
288
|
+
return props[property];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return null;
|
|
292
|
+
};
|
|
293
|
+
var getTitleFromPropsList = (propsList) => {
|
|
294
|
+
let innermostTitle = getInnermostProperty(
|
|
295
|
+
propsList,
|
|
296
|
+
"title"
|
|
297
|
+
/* TITLE */
|
|
298
|
+
);
|
|
299
|
+
const innermostTemplate = getInnermostProperty(propsList, HELMET_PROPS.TITLE_TEMPLATE);
|
|
300
|
+
if (Array.isArray(innermostTitle)) {
|
|
301
|
+
innermostTitle = innermostTitle.join("");
|
|
302
|
+
}
|
|
303
|
+
if (innermostTemplate && innermostTitle) {
|
|
304
|
+
return innermostTemplate.replace(/%s/g, () => innermostTitle);
|
|
305
|
+
}
|
|
306
|
+
const innermostDefaultTitle = getInnermostProperty(propsList, HELMET_PROPS.DEFAULT_TITLE);
|
|
307
|
+
return innermostTitle || innermostDefaultTitle || void 0;
|
|
308
|
+
};
|
|
309
|
+
var getOnChangeClientState = (propsList) => getInnermostProperty(propsList, HELMET_PROPS.ON_CHANGE_CLIENT_STATE) || (() => {
|
|
310
|
+
});
|
|
311
|
+
var getAttributesFromPropsList = (tagType, propsList) => propsList.filter((props) => typeof props[tagType] !== "undefined").map((props) => props[tagType]).reduce((tagAttrs, current) => ({ ...tagAttrs, ...current }), {});
|
|
312
|
+
var getBaseTagFromPropsList = (primaryAttributes, propsList) => propsList.filter((props) => typeof props[
|
|
313
|
+
"base"
|
|
314
|
+
/* BASE */
|
|
315
|
+
] !== "undefined").map((props) => props[
|
|
316
|
+
"base"
|
|
317
|
+
/* BASE */
|
|
318
|
+
]).reverse().reduce((innermostBaseTag, tag) => {
|
|
319
|
+
if (!innermostBaseTag.length) {
|
|
320
|
+
const keys = Object.keys(tag);
|
|
321
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
322
|
+
const attributeKey = keys[i];
|
|
323
|
+
const lowerCaseAttributeKey = attributeKey.toLowerCase();
|
|
324
|
+
if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && tag[lowerCaseAttributeKey]) {
|
|
325
|
+
return innermostBaseTag.concat(tag);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return innermostBaseTag;
|
|
330
|
+
}, []);
|
|
331
|
+
var warn = (msg) => console && typeof console.warn === "function" && console.warn(msg);
|
|
332
|
+
var getTagsFromPropsList = (tagName, primaryAttributes, propsList) => {
|
|
333
|
+
const approvedSeenTags = {};
|
|
334
|
+
return propsList.filter((props) => {
|
|
335
|
+
if (Array.isArray(props[tagName])) {
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
if (typeof props[tagName] !== "undefined") {
|
|
339
|
+
warn(
|
|
340
|
+
`Helmet: ${tagName} should be of type "Array". Instead found type "${typeof props[tagName]}"`
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
return false;
|
|
344
|
+
}).map((props) => props[tagName]).reverse().reduce((approvedTags, instanceTags) => {
|
|
345
|
+
const instanceSeenTags = {};
|
|
346
|
+
instanceTags.filter((tag) => {
|
|
347
|
+
let primaryAttributeKey;
|
|
348
|
+
const keys2 = Object.keys(tag);
|
|
349
|
+
for (let i = 0; i < keys2.length; i += 1) {
|
|
350
|
+
const attributeKey = keys2[i];
|
|
351
|
+
const lowerCaseAttributeKey = attributeKey.toLowerCase();
|
|
352
|
+
if (primaryAttributes.indexOf(lowerCaseAttributeKey) !== -1 && !(primaryAttributeKey === "rel" && tag[primaryAttributeKey].toLowerCase() === "canonical") && !(lowerCaseAttributeKey === "rel" && tag[lowerCaseAttributeKey].toLowerCase() === "stylesheet")) {
|
|
353
|
+
primaryAttributeKey = lowerCaseAttributeKey;
|
|
354
|
+
}
|
|
355
|
+
if (primaryAttributes.indexOf(attributeKey) !== -1 && (attributeKey === "innerHTML" || attributeKey === "cssText" || attributeKey === "itemprop")) {
|
|
356
|
+
primaryAttributeKey = attributeKey;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if (!primaryAttributeKey || !tag[primaryAttributeKey]) {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
const value = tag[primaryAttributeKey].toLowerCase();
|
|
363
|
+
if (!approvedSeenTags[primaryAttributeKey]) {
|
|
364
|
+
approvedSeenTags[primaryAttributeKey] = {};
|
|
365
|
+
}
|
|
366
|
+
if (!instanceSeenTags[primaryAttributeKey]) {
|
|
367
|
+
instanceSeenTags[primaryAttributeKey] = {};
|
|
368
|
+
}
|
|
369
|
+
if (!approvedSeenTags[primaryAttributeKey][value]) {
|
|
370
|
+
instanceSeenTags[primaryAttributeKey][value] = true;
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
return false;
|
|
374
|
+
}).reverse().forEach((tag) => approvedTags.push(tag));
|
|
375
|
+
const keys = Object.keys(instanceSeenTags);
|
|
376
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
377
|
+
const attributeKey = keys[i];
|
|
378
|
+
const tagUnion = {
|
|
379
|
+
...approvedSeenTags[attributeKey],
|
|
380
|
+
...instanceSeenTags[attributeKey]
|
|
381
|
+
};
|
|
382
|
+
approvedSeenTags[attributeKey] = tagUnion;
|
|
383
|
+
}
|
|
384
|
+
return approvedTags;
|
|
385
|
+
}, []).reverse();
|
|
386
|
+
};
|
|
387
|
+
var getAnyTrueFromPropsList = (propsList, checkedTag) => {
|
|
388
|
+
if (Array.isArray(propsList) && propsList.length) {
|
|
389
|
+
for (let index = 0; index < propsList.length; index += 1) {
|
|
390
|
+
const prop = propsList[index];
|
|
391
|
+
if (prop[checkedTag]) {
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return false;
|
|
397
|
+
};
|
|
398
|
+
var reducePropsToState = (propsList) => ({
|
|
399
|
+
baseTag: getBaseTagFromPropsList([
|
|
400
|
+
"href"
|
|
401
|
+
/* HREF */
|
|
402
|
+
], propsList),
|
|
403
|
+
bodyAttributes: getAttributesFromPropsList("bodyAttributes", propsList),
|
|
404
|
+
defer: getInnermostProperty(propsList, HELMET_PROPS.DEFER),
|
|
405
|
+
encode: getInnermostProperty(propsList, HELMET_PROPS.ENCODE_SPECIAL_CHARACTERS),
|
|
406
|
+
htmlAttributes: getAttributesFromPropsList("htmlAttributes", propsList),
|
|
407
|
+
linkTags: getTagsFromPropsList(
|
|
408
|
+
"link",
|
|
409
|
+
[
|
|
410
|
+
"rel",
|
|
411
|
+
"href"
|
|
412
|
+
/* HREF */
|
|
413
|
+
],
|
|
414
|
+
propsList
|
|
415
|
+
),
|
|
416
|
+
metaTags: getTagsFromPropsList(
|
|
417
|
+
"meta",
|
|
418
|
+
[
|
|
419
|
+
"name",
|
|
420
|
+
"charset",
|
|
421
|
+
"http-equiv",
|
|
422
|
+
"property",
|
|
423
|
+
"itemprop"
|
|
424
|
+
/* ITEM_PROP */
|
|
425
|
+
],
|
|
426
|
+
propsList
|
|
427
|
+
),
|
|
428
|
+
noscriptTags: getTagsFromPropsList("noscript", [
|
|
429
|
+
"innerHTML"
|
|
430
|
+
/* INNER_HTML */
|
|
431
|
+
], propsList),
|
|
432
|
+
onChangeClientState: getOnChangeClientState(propsList),
|
|
433
|
+
scriptTags: getTagsFromPropsList(
|
|
434
|
+
"script",
|
|
435
|
+
[
|
|
436
|
+
"src",
|
|
437
|
+
"innerHTML"
|
|
438
|
+
/* INNER_HTML */
|
|
439
|
+
],
|
|
440
|
+
propsList
|
|
441
|
+
),
|
|
442
|
+
styleTags: getTagsFromPropsList("style", [
|
|
443
|
+
"cssText"
|
|
444
|
+
/* CSS_TEXT */
|
|
445
|
+
], propsList),
|
|
446
|
+
title: getTitleFromPropsList(propsList),
|
|
447
|
+
titleAttributes: getAttributesFromPropsList("titleAttributes", propsList),
|
|
448
|
+
prioritizeSeoTags: getAnyTrueFromPropsList(propsList, HELMET_PROPS.PRIORITIZE_SEO_TAGS)
|
|
449
|
+
});
|
|
450
|
+
var flattenArray = (possibleArray) => Array.isArray(possibleArray) ? possibleArray.join("") : possibleArray;
|
|
451
|
+
var checkIfPropsMatch = (props, toMatch) => {
|
|
452
|
+
const keys = Object.keys(props);
|
|
453
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
454
|
+
if (toMatch[keys[i]] && toMatch[keys[i]].includes(props[keys[i]])) {
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return false;
|
|
459
|
+
};
|
|
460
|
+
var prioritizer = (elementsList, propsToMatch) => {
|
|
461
|
+
if (Array.isArray(elementsList)) {
|
|
462
|
+
return elementsList.reduce(
|
|
463
|
+
(acc, elementAttrs) => {
|
|
464
|
+
if (checkIfPropsMatch(elementAttrs, propsToMatch)) {
|
|
465
|
+
acc.priority.push(elementAttrs);
|
|
466
|
+
} else {
|
|
467
|
+
acc.default.push(elementAttrs);
|
|
468
|
+
}
|
|
469
|
+
return acc;
|
|
470
|
+
},
|
|
471
|
+
{ priority: [], default: [] }
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
return { default: elementsList, priority: [] };
|
|
475
|
+
};
|
|
476
|
+
var without = (obj, key) => {
|
|
477
|
+
return {
|
|
478
|
+
...obj,
|
|
479
|
+
[key]: void 0
|
|
480
|
+
};
|
|
481
|
+
};
|
|
482
|
+
var SELF_CLOSING_TAGS = [
|
|
483
|
+
"noscript",
|
|
484
|
+
"script",
|
|
485
|
+
"style"
|
|
486
|
+
/* STYLE */
|
|
487
|
+
];
|
|
488
|
+
var encodeSpecialCharacters = (str, encode = true) => {
|
|
489
|
+
if (encode === false) {
|
|
490
|
+
return String(str);
|
|
491
|
+
}
|
|
492
|
+
return String(str).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
493
|
+
};
|
|
494
|
+
var generateElementAttributesAsString = (attributes) => Object.keys(attributes).reduce((str, key) => {
|
|
495
|
+
const attr = typeof attributes[key] !== "undefined" ? `${key}="${attributes[key]}"` : `${key}`;
|
|
496
|
+
return str ? `${str} ${attr}` : attr;
|
|
497
|
+
}, "");
|
|
498
|
+
var generateTitleAsString = (type, title, attributes, encode) => {
|
|
499
|
+
const attributeString = generateElementAttributesAsString(attributes);
|
|
500
|
+
const flattenedTitle = flattenArray(title);
|
|
501
|
+
return attributeString ? `<${type} ${HELMET_ATTRIBUTE}="true" ${attributeString}>${encodeSpecialCharacters(
|
|
502
|
+
flattenedTitle,
|
|
503
|
+
encode
|
|
504
|
+
)}</${type}>` : `<${type} ${HELMET_ATTRIBUTE}="true">${encodeSpecialCharacters(
|
|
505
|
+
flattenedTitle,
|
|
506
|
+
encode
|
|
507
|
+
)}</${type}>`;
|
|
508
|
+
};
|
|
509
|
+
var generateTagsAsString = (type, tags, encode = true) => tags.reduce((str, t) => {
|
|
510
|
+
const tag = t;
|
|
511
|
+
const attributeHtml = Object.keys(tag).filter(
|
|
512
|
+
(attribute) => !(attribute === "innerHTML" || attribute === "cssText")
|
|
513
|
+
).reduce((string, attribute) => {
|
|
514
|
+
const attr = typeof tag[attribute] === "undefined" ? attribute : `${attribute}="${encodeSpecialCharacters(tag[attribute], encode)}"`;
|
|
515
|
+
return string ? `${string} ${attr}` : attr;
|
|
516
|
+
}, "");
|
|
517
|
+
const tagContent = tag.innerHTML || tag.cssText || "";
|
|
518
|
+
const isSelfClosing = SELF_CLOSING_TAGS.indexOf(type) === -1;
|
|
519
|
+
return `${str}<${type} ${HELMET_ATTRIBUTE}="true" ${attributeHtml}${isSelfClosing ? `/>` : `>${tagContent}</${type}>`}`;
|
|
520
|
+
}, "");
|
|
521
|
+
var convertElementAttributesToReactProps = (attributes, initProps = {}) => Object.keys(attributes).reduce((obj, key) => {
|
|
522
|
+
const mapped = REACT_TAG_MAP[key];
|
|
523
|
+
obj[mapped || key] = attributes[key];
|
|
524
|
+
return obj;
|
|
525
|
+
}, initProps);
|
|
526
|
+
var generateTitleAsReactComponent = (_type, title, attributes) => {
|
|
527
|
+
const initProps = {
|
|
528
|
+
key: title,
|
|
529
|
+
[HELMET_ATTRIBUTE]: true
|
|
530
|
+
};
|
|
531
|
+
const props = convertElementAttributesToReactProps(attributes, initProps);
|
|
532
|
+
return [import_react3.default.createElement("title", props, title)];
|
|
533
|
+
};
|
|
534
|
+
var generateTagsAsReactComponent = (type, tags) => tags.map((tag, i) => {
|
|
535
|
+
const mappedTag = {
|
|
536
|
+
key: i,
|
|
537
|
+
[HELMET_ATTRIBUTE]: true
|
|
538
|
+
};
|
|
539
|
+
Object.keys(tag).forEach((attribute) => {
|
|
540
|
+
const mapped = REACT_TAG_MAP[attribute];
|
|
541
|
+
const mappedAttribute = mapped || attribute;
|
|
542
|
+
if (mappedAttribute === "innerHTML" || mappedAttribute === "cssText") {
|
|
543
|
+
const content = tag.innerHTML || tag.cssText;
|
|
544
|
+
mappedTag.dangerouslySetInnerHTML = { __html: content };
|
|
545
|
+
} else {
|
|
546
|
+
mappedTag[mappedAttribute] = tag[attribute];
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
return import_react3.default.createElement(type, mappedTag);
|
|
550
|
+
});
|
|
551
|
+
var getMethodsForTag = (type, tags, encode = true) => {
|
|
552
|
+
switch (type) {
|
|
553
|
+
case "title":
|
|
554
|
+
return {
|
|
555
|
+
toComponent: () => generateTitleAsReactComponent(type, tags.title, tags.titleAttributes),
|
|
556
|
+
toString: () => generateTitleAsString(type, tags.title, tags.titleAttributes, encode)
|
|
557
|
+
};
|
|
558
|
+
case "bodyAttributes":
|
|
559
|
+
case "htmlAttributes":
|
|
560
|
+
return {
|
|
561
|
+
toComponent: () => convertElementAttributesToReactProps(tags),
|
|
562
|
+
toString: () => generateElementAttributesAsString(tags)
|
|
563
|
+
};
|
|
564
|
+
default:
|
|
565
|
+
return {
|
|
566
|
+
toComponent: () => generateTagsAsReactComponent(type, tags),
|
|
567
|
+
toString: () => generateTagsAsString(type, tags, encode)
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
var getPriorityMethods = ({ metaTags, linkTags, scriptTags, encode }) => {
|
|
572
|
+
const meta = prioritizer(metaTags, SEO_PRIORITY_TAGS.meta);
|
|
573
|
+
const link = prioritizer(linkTags, SEO_PRIORITY_TAGS.link);
|
|
574
|
+
const script = prioritizer(scriptTags, SEO_PRIORITY_TAGS.script);
|
|
575
|
+
const priorityMethods = {
|
|
576
|
+
toComponent: () => [
|
|
577
|
+
...generateTagsAsReactComponent("meta", meta.priority),
|
|
578
|
+
...generateTagsAsReactComponent("link", link.priority),
|
|
579
|
+
...generateTagsAsReactComponent("script", script.priority)
|
|
580
|
+
],
|
|
581
|
+
toString: () => (
|
|
582
|
+
// generate all the tags as strings and concatenate them
|
|
583
|
+
`${getMethodsForTag("meta", meta.priority, encode)} ${getMethodsForTag(
|
|
584
|
+
"link",
|
|
585
|
+
link.priority,
|
|
586
|
+
encode
|
|
587
|
+
)} ${getMethodsForTag("script", script.priority, encode)}`
|
|
588
|
+
)
|
|
589
|
+
};
|
|
590
|
+
return {
|
|
591
|
+
priorityMethods,
|
|
592
|
+
metaTags: meta.default,
|
|
593
|
+
linkTags: link.default,
|
|
594
|
+
scriptTags: script.default
|
|
595
|
+
};
|
|
596
|
+
};
|
|
597
|
+
var mapStateOnServer = (props) => {
|
|
598
|
+
const {
|
|
599
|
+
baseTag,
|
|
600
|
+
bodyAttributes,
|
|
601
|
+
encode = true,
|
|
602
|
+
htmlAttributes,
|
|
603
|
+
noscriptTags,
|
|
604
|
+
styleTags,
|
|
605
|
+
title = "",
|
|
606
|
+
titleAttributes,
|
|
607
|
+
prioritizeSeoTags
|
|
608
|
+
} = props;
|
|
609
|
+
let { linkTags, metaTags, scriptTags } = props;
|
|
610
|
+
let priorityMethods = {
|
|
611
|
+
toComponent: () => {
|
|
612
|
+
},
|
|
613
|
+
toString: () => ""
|
|
614
|
+
};
|
|
615
|
+
if (prioritizeSeoTags) {
|
|
616
|
+
({ priorityMethods, linkTags, metaTags, scriptTags } = getPriorityMethods(props));
|
|
617
|
+
}
|
|
618
|
+
return {
|
|
619
|
+
priority: priorityMethods,
|
|
620
|
+
base: getMethodsForTag("base", baseTag, encode),
|
|
621
|
+
bodyAttributes: getMethodsForTag("bodyAttributes", bodyAttributes, encode),
|
|
622
|
+
htmlAttributes: getMethodsForTag("htmlAttributes", htmlAttributes, encode),
|
|
623
|
+
link: getMethodsForTag("link", linkTags, encode),
|
|
624
|
+
meta: getMethodsForTag("meta", metaTags, encode),
|
|
625
|
+
noscript: getMethodsForTag("noscript", noscriptTags, encode),
|
|
626
|
+
script: getMethodsForTag("script", scriptTags, encode),
|
|
627
|
+
style: getMethodsForTag("style", styleTags, encode),
|
|
628
|
+
title: getMethodsForTag("title", { title, titleAttributes }, encode)
|
|
629
|
+
};
|
|
630
|
+
};
|
|
631
|
+
var server_default = mapStateOnServer;
|
|
632
|
+
var instances = [];
|
|
633
|
+
var isDocument = !!(typeof window !== "undefined" && window.document && window.document.createElement);
|
|
634
|
+
var HelmetData = class {
|
|
635
|
+
instances = [];
|
|
636
|
+
canUseDOM = isDocument;
|
|
637
|
+
context;
|
|
638
|
+
value = {
|
|
639
|
+
setHelmet: (serverState) => {
|
|
640
|
+
this.context.helmet = serverState;
|
|
641
|
+
},
|
|
642
|
+
helmetInstances: {
|
|
643
|
+
get: () => this.canUseDOM ? instances : this.instances,
|
|
644
|
+
add: (instance) => {
|
|
645
|
+
(this.canUseDOM ? instances : this.instances).push(instance);
|
|
646
|
+
},
|
|
647
|
+
remove: (instance) => {
|
|
648
|
+
const index = (this.canUseDOM ? instances : this.instances).indexOf(instance);
|
|
649
|
+
(this.canUseDOM ? instances : this.instances).splice(index, 1);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
constructor(context, canUseDOM) {
|
|
654
|
+
this.context = context;
|
|
655
|
+
this.canUseDOM = canUseDOM || false;
|
|
656
|
+
if (!canUseDOM) {
|
|
657
|
+
context.helmet = server_default({
|
|
658
|
+
baseTag: [],
|
|
659
|
+
bodyAttributes: {},
|
|
660
|
+
encodeSpecialCharacters: true,
|
|
661
|
+
htmlAttributes: {},
|
|
662
|
+
linkTags: [],
|
|
663
|
+
metaTags: [],
|
|
664
|
+
noscriptTags: [],
|
|
665
|
+
scriptTags: [],
|
|
666
|
+
styleTags: [],
|
|
667
|
+
title: "",
|
|
668
|
+
titleAttributes: {}
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
var defaultValue = {};
|
|
674
|
+
var Context = import_react2.default.createContext(defaultValue);
|
|
675
|
+
var HelmetProvider = class _HelmetProvider extends import_react2.Component {
|
|
676
|
+
static canUseDOM = isDocument;
|
|
677
|
+
helmetData;
|
|
678
|
+
constructor(props) {
|
|
679
|
+
super(props);
|
|
680
|
+
this.helmetData = new HelmetData(this.props.context || {}, _HelmetProvider.canUseDOM);
|
|
681
|
+
}
|
|
682
|
+
render() {
|
|
683
|
+
return /* @__PURE__ */ import_react2.default.createElement(Context.Provider, { value: this.helmetData.value }, this.props.children);
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
var updateTags = (type, tags) => {
|
|
687
|
+
const headElement = document.head || document.querySelector(
|
|
688
|
+
"head"
|
|
689
|
+
/* HEAD */
|
|
690
|
+
);
|
|
691
|
+
const tagNodes = headElement.querySelectorAll(`${type}[${HELMET_ATTRIBUTE}]`);
|
|
692
|
+
const oldTags = [].slice.call(tagNodes);
|
|
693
|
+
const newTags = [];
|
|
694
|
+
let indexToDelete;
|
|
695
|
+
if (tags && tags.length) {
|
|
696
|
+
tags.forEach((tag) => {
|
|
697
|
+
const newElement = document.createElement(type);
|
|
698
|
+
for (const attribute in tag) {
|
|
699
|
+
if (Object.prototype.hasOwnProperty.call(tag, attribute)) {
|
|
700
|
+
if (attribute === "innerHTML") {
|
|
701
|
+
newElement.innerHTML = tag.innerHTML;
|
|
702
|
+
} else if (attribute === "cssText") {
|
|
703
|
+
if (newElement.styleSheet) {
|
|
704
|
+
newElement.styleSheet.cssText = tag.cssText;
|
|
705
|
+
} else {
|
|
706
|
+
newElement.appendChild(document.createTextNode(tag.cssText));
|
|
707
|
+
}
|
|
708
|
+
} else {
|
|
709
|
+
const attr = attribute;
|
|
710
|
+
const value = typeof tag[attr] === "undefined" ? "" : tag[attr];
|
|
711
|
+
newElement.setAttribute(attribute, value);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
newElement.setAttribute(HELMET_ATTRIBUTE, "true");
|
|
716
|
+
if (oldTags.some((existingTag, index) => {
|
|
717
|
+
indexToDelete = index;
|
|
718
|
+
return newElement.isEqualNode(existingTag);
|
|
719
|
+
})) {
|
|
720
|
+
oldTags.splice(indexToDelete, 1);
|
|
721
|
+
} else {
|
|
722
|
+
newTags.push(newElement);
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
oldTags.forEach((tag) => tag.parentNode?.removeChild(tag));
|
|
727
|
+
newTags.forEach((tag) => headElement.appendChild(tag));
|
|
728
|
+
return {
|
|
729
|
+
oldTags,
|
|
730
|
+
newTags
|
|
731
|
+
};
|
|
732
|
+
};
|
|
733
|
+
var updateAttributes = (tagName, attributes) => {
|
|
734
|
+
const elementTag = document.getElementsByTagName(tagName)[0];
|
|
735
|
+
if (!elementTag) {
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
const helmetAttributeString = elementTag.getAttribute(HELMET_ATTRIBUTE);
|
|
739
|
+
const helmetAttributes = helmetAttributeString ? helmetAttributeString.split(",") : [];
|
|
740
|
+
const attributesToRemove = [...helmetAttributes];
|
|
741
|
+
const attributeKeys = Object.keys(attributes);
|
|
742
|
+
for (const attribute of attributeKeys) {
|
|
743
|
+
const value = attributes[attribute] || "";
|
|
744
|
+
if (elementTag.getAttribute(attribute) !== value) {
|
|
745
|
+
elementTag.setAttribute(attribute, value);
|
|
746
|
+
}
|
|
747
|
+
if (helmetAttributes.indexOf(attribute) === -1) {
|
|
748
|
+
helmetAttributes.push(attribute);
|
|
749
|
+
}
|
|
750
|
+
const indexToSave = attributesToRemove.indexOf(attribute);
|
|
751
|
+
if (indexToSave !== -1) {
|
|
752
|
+
attributesToRemove.splice(indexToSave, 1);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
for (let i = attributesToRemove.length - 1; i >= 0; i -= 1) {
|
|
756
|
+
elementTag.removeAttribute(attributesToRemove[i]);
|
|
757
|
+
}
|
|
758
|
+
if (helmetAttributes.length === attributesToRemove.length) {
|
|
759
|
+
elementTag.removeAttribute(HELMET_ATTRIBUTE);
|
|
760
|
+
} else if (elementTag.getAttribute(HELMET_ATTRIBUTE) !== attributeKeys.join(",")) {
|
|
761
|
+
elementTag.setAttribute(HELMET_ATTRIBUTE, attributeKeys.join(","));
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
var updateTitle = (title, attributes) => {
|
|
765
|
+
if (typeof title !== "undefined" && document.title !== title) {
|
|
766
|
+
document.title = flattenArray(title);
|
|
767
|
+
}
|
|
768
|
+
updateAttributes("title", attributes);
|
|
769
|
+
};
|
|
770
|
+
var commitTagChanges = (newState, cb) => {
|
|
771
|
+
const {
|
|
772
|
+
baseTag,
|
|
773
|
+
bodyAttributes,
|
|
774
|
+
htmlAttributes,
|
|
775
|
+
linkTags,
|
|
776
|
+
metaTags,
|
|
777
|
+
noscriptTags,
|
|
778
|
+
onChangeClientState,
|
|
779
|
+
scriptTags,
|
|
780
|
+
styleTags,
|
|
781
|
+
title,
|
|
782
|
+
titleAttributes
|
|
783
|
+
} = newState;
|
|
784
|
+
updateAttributes("body", bodyAttributes);
|
|
785
|
+
updateAttributes("html", htmlAttributes);
|
|
786
|
+
updateTitle(title, titleAttributes);
|
|
787
|
+
const tagUpdates = {
|
|
788
|
+
baseTag: updateTags("base", baseTag),
|
|
789
|
+
linkTags: updateTags("link", linkTags),
|
|
790
|
+
metaTags: updateTags("meta", metaTags),
|
|
791
|
+
noscriptTags: updateTags("noscript", noscriptTags),
|
|
792
|
+
scriptTags: updateTags("script", scriptTags),
|
|
793
|
+
styleTags: updateTags("style", styleTags)
|
|
794
|
+
};
|
|
795
|
+
const addedTags = {};
|
|
796
|
+
const removedTags = {};
|
|
797
|
+
Object.keys(tagUpdates).forEach((tagType) => {
|
|
798
|
+
const { newTags, oldTags } = tagUpdates[tagType];
|
|
799
|
+
if (newTags.length) {
|
|
800
|
+
addedTags[tagType] = newTags;
|
|
801
|
+
}
|
|
802
|
+
if (oldTags.length) {
|
|
803
|
+
removedTags[tagType] = tagUpdates[tagType].oldTags;
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
if (cb) {
|
|
807
|
+
cb();
|
|
808
|
+
}
|
|
809
|
+
onChangeClientState(newState, addedTags, removedTags);
|
|
810
|
+
};
|
|
811
|
+
var _helmetCallback = null;
|
|
812
|
+
var handleStateChangeOnClient = (newState) => {
|
|
813
|
+
if (_helmetCallback) {
|
|
814
|
+
cancelAnimationFrame(_helmetCallback);
|
|
815
|
+
}
|
|
816
|
+
if (newState.defer) {
|
|
817
|
+
_helmetCallback = requestAnimationFrame(() => {
|
|
818
|
+
commitTagChanges(newState, () => {
|
|
819
|
+
_helmetCallback = null;
|
|
820
|
+
});
|
|
821
|
+
});
|
|
822
|
+
} else {
|
|
823
|
+
commitTagChanges(newState);
|
|
824
|
+
_helmetCallback = null;
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
var client_default = handleStateChangeOnClient;
|
|
828
|
+
var HelmetDispatcher = class extends import_react4.Component {
|
|
829
|
+
rendered = false;
|
|
830
|
+
shouldComponentUpdate(nextProps) {
|
|
831
|
+
return !(0, import_shallowequal.default)(nextProps, this.props);
|
|
832
|
+
}
|
|
833
|
+
componentDidUpdate() {
|
|
834
|
+
this.emitChange();
|
|
835
|
+
}
|
|
836
|
+
componentWillUnmount() {
|
|
837
|
+
const { helmetInstances } = this.props.context;
|
|
838
|
+
helmetInstances.remove(this);
|
|
839
|
+
this.emitChange();
|
|
840
|
+
}
|
|
841
|
+
emitChange() {
|
|
842
|
+
const { helmetInstances, setHelmet } = this.props.context;
|
|
843
|
+
let serverState = null;
|
|
844
|
+
const state = reducePropsToState(
|
|
845
|
+
helmetInstances.get().map((instance) => {
|
|
846
|
+
const props = { ...instance.props };
|
|
847
|
+
delete props.context;
|
|
848
|
+
return props;
|
|
849
|
+
})
|
|
850
|
+
);
|
|
851
|
+
if (HelmetProvider.canUseDOM) {
|
|
852
|
+
client_default(state);
|
|
853
|
+
} else if (server_default) {
|
|
854
|
+
serverState = server_default(state);
|
|
855
|
+
}
|
|
856
|
+
setHelmet(serverState);
|
|
857
|
+
}
|
|
858
|
+
// componentWillMount will be deprecated
|
|
859
|
+
// for SSR, initialize on first render
|
|
860
|
+
// constructor is also unsafe in StrictMode
|
|
861
|
+
init() {
|
|
862
|
+
if (this.rendered) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
this.rendered = true;
|
|
866
|
+
const { helmetInstances } = this.props.context;
|
|
867
|
+
helmetInstances.add(this);
|
|
868
|
+
this.emitChange();
|
|
869
|
+
}
|
|
870
|
+
render() {
|
|
871
|
+
this.init();
|
|
872
|
+
return null;
|
|
873
|
+
}
|
|
874
|
+
};
|
|
875
|
+
var Helmet = class extends import_react.Component {
|
|
876
|
+
static defaultProps = {
|
|
877
|
+
defer: true,
|
|
878
|
+
encodeSpecialCharacters: true,
|
|
879
|
+
prioritizeSeoTags: false
|
|
880
|
+
};
|
|
881
|
+
shouldComponentUpdate(nextProps) {
|
|
882
|
+
return !(0, import_react_fast_compare.default)(without(this.props, "helmetData"), without(nextProps, "helmetData"));
|
|
883
|
+
}
|
|
884
|
+
mapNestedChildrenToProps(child, nestedChildren) {
|
|
885
|
+
if (!nestedChildren) {
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
888
|
+
switch (child.type) {
|
|
889
|
+
case "script":
|
|
890
|
+
case "noscript":
|
|
891
|
+
return {
|
|
892
|
+
innerHTML: nestedChildren
|
|
893
|
+
};
|
|
894
|
+
case "style":
|
|
895
|
+
return {
|
|
896
|
+
cssText: nestedChildren
|
|
897
|
+
};
|
|
898
|
+
default:
|
|
899
|
+
throw new Error(
|
|
900
|
+
`<${child.type} /> elements are self-closing and can not contain children. Refer to our API for more information.`
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
flattenArrayTypeChildren(child, arrayTypeChildren, newChildProps, nestedChildren) {
|
|
905
|
+
return {
|
|
906
|
+
...arrayTypeChildren,
|
|
907
|
+
[child.type]: [
|
|
908
|
+
...arrayTypeChildren[child.type] || [],
|
|
909
|
+
{
|
|
910
|
+
...newChildProps,
|
|
911
|
+
...this.mapNestedChildrenToProps(child, nestedChildren)
|
|
912
|
+
}
|
|
913
|
+
]
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
mapObjectTypeChildren(child, newProps, newChildProps, nestedChildren) {
|
|
917
|
+
switch (child.type) {
|
|
918
|
+
case "title":
|
|
919
|
+
return {
|
|
920
|
+
...newProps,
|
|
921
|
+
[child.type]: nestedChildren,
|
|
922
|
+
titleAttributes: { ...newChildProps }
|
|
923
|
+
};
|
|
924
|
+
case "body":
|
|
925
|
+
return {
|
|
926
|
+
...newProps,
|
|
927
|
+
bodyAttributes: { ...newChildProps }
|
|
928
|
+
};
|
|
929
|
+
case "html":
|
|
930
|
+
return {
|
|
931
|
+
...newProps,
|
|
932
|
+
htmlAttributes: { ...newChildProps }
|
|
933
|
+
};
|
|
934
|
+
default:
|
|
935
|
+
return {
|
|
936
|
+
...newProps,
|
|
937
|
+
[child.type]: { ...newChildProps }
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
mapArrayTypeChildrenToProps(arrayTypeChildren, newProps) {
|
|
942
|
+
let newFlattenedProps = { ...newProps };
|
|
943
|
+
Object.keys(arrayTypeChildren).forEach((arrayChildName) => {
|
|
944
|
+
newFlattenedProps = {
|
|
945
|
+
...newFlattenedProps,
|
|
946
|
+
[arrayChildName]: arrayTypeChildren[arrayChildName]
|
|
947
|
+
};
|
|
948
|
+
});
|
|
949
|
+
return newFlattenedProps;
|
|
950
|
+
}
|
|
951
|
+
warnOnInvalidChildren(child, nestedChildren) {
|
|
952
|
+
(0, import_invariant.default)(
|
|
953
|
+
VALID_TAG_NAMES.some((name) => child.type === name),
|
|
954
|
+
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(
|
|
955
|
+
", "
|
|
956
|
+
)} are allowed. Helmet does not support rendering <${child.type}> elements. Refer to our API for more information.`
|
|
957
|
+
);
|
|
958
|
+
(0, import_invariant.default)(
|
|
959
|
+
!nestedChildren || typeof nestedChildren === "string" || Array.isArray(nestedChildren) && !nestedChildren.some((nestedChild) => typeof nestedChild !== "string"),
|
|
960
|
+
`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.`
|
|
961
|
+
);
|
|
962
|
+
return true;
|
|
963
|
+
}
|
|
964
|
+
mapChildrenToProps(children, newProps) {
|
|
965
|
+
let arrayTypeChildren = {};
|
|
966
|
+
import_react.default.Children.forEach(children, (child) => {
|
|
967
|
+
if (!child || !child.props) {
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
const { children: nestedChildren, ...childProps } = child.props;
|
|
971
|
+
const newChildProps = Object.keys(childProps).reduce((obj, key) => {
|
|
972
|
+
obj[HTML_TAG_MAP[key] || key] = childProps[key];
|
|
973
|
+
return obj;
|
|
974
|
+
}, {});
|
|
975
|
+
let { type } = child;
|
|
976
|
+
if (typeof type === "symbol") {
|
|
977
|
+
type = type.toString();
|
|
978
|
+
} else {
|
|
979
|
+
this.warnOnInvalidChildren(child, nestedChildren);
|
|
980
|
+
}
|
|
981
|
+
switch (type) {
|
|
982
|
+
case "Symbol(react.fragment)":
|
|
983
|
+
newProps = this.mapChildrenToProps(nestedChildren, newProps);
|
|
984
|
+
break;
|
|
985
|
+
case "link":
|
|
986
|
+
case "meta":
|
|
987
|
+
case "noscript":
|
|
988
|
+
case "script":
|
|
989
|
+
case "style":
|
|
990
|
+
arrayTypeChildren = this.flattenArrayTypeChildren(
|
|
991
|
+
child,
|
|
992
|
+
arrayTypeChildren,
|
|
993
|
+
newChildProps,
|
|
994
|
+
nestedChildren
|
|
995
|
+
);
|
|
996
|
+
break;
|
|
997
|
+
default:
|
|
998
|
+
newProps = this.mapObjectTypeChildren(child, newProps, newChildProps, nestedChildren);
|
|
999
|
+
break;
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
return this.mapArrayTypeChildrenToProps(arrayTypeChildren, newProps);
|
|
1003
|
+
}
|
|
1004
|
+
render() {
|
|
1005
|
+
const { children, ...props } = this.props;
|
|
1006
|
+
let newProps = { ...props };
|
|
1007
|
+
let { helmetData } = props;
|
|
1008
|
+
if (children) {
|
|
1009
|
+
newProps = this.mapChildrenToProps(children, newProps);
|
|
1010
|
+
}
|
|
1011
|
+
if (helmetData && !(helmetData instanceof HelmetData)) {
|
|
1012
|
+
const data = helmetData;
|
|
1013
|
+
helmetData = new HelmetData(data.context, true);
|
|
1014
|
+
delete newProps.helmetData;
|
|
1015
|
+
}
|
|
1016
|
+
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 }));
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
// src/components/SEOProvider.tsx
|
|
1021
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1022
|
+
var SEOContext = (0, import_react5.createContext)(void 0);
|
|
1023
|
+
var SEOProvider = ({ config, children, helmetContext }) => {
|
|
1024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SEOContext.Provider, { value: { config }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HelmetProvider, { context: helmetContext, children }) });
|
|
1025
|
+
};
|
|
1026
|
+
var useSEOConfig = () => {
|
|
1027
|
+
const context = (0, import_react5.useContext)(SEOContext);
|
|
1028
|
+
if (!context) {
|
|
1029
|
+
throw new Error("useSEOConfig must be used within an SEOProvider");
|
|
1030
|
+
}
|
|
1031
|
+
return context.config;
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
// src/components/SEO.tsx
|
|
1035
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1036
|
+
var SEO = (props) => {
|
|
1037
|
+
const config = useSEOConfig();
|
|
1038
|
+
const title = props.title ? `${props.title} | ${config.name}` : config.name;
|
|
1039
|
+
const description = props.description || config.description;
|
|
1040
|
+
const url = props.canonical || (typeof window !== "undefined" ? window.location.href : config.url);
|
|
1041
|
+
const image = props.image || config.logo;
|
|
1042
|
+
const schemas = [];
|
|
1043
|
+
const organizationSchema = {
|
|
1044
|
+
"@context": "https://schema.org",
|
|
1045
|
+
"@type": "Organization",
|
|
1046
|
+
"name": config.name,
|
|
1047
|
+
"url": config.url,
|
|
1048
|
+
"logo": config.logo,
|
|
1049
|
+
"sameAs": config.socialLinks || []
|
|
1050
|
+
};
|
|
1051
|
+
const websiteSchema = {
|
|
1052
|
+
"@context": "https://schema.org",
|
|
1053
|
+
"@type": "WebSite",
|
|
1054
|
+
"name": config.name,
|
|
1055
|
+
"url": config.url,
|
|
1056
|
+
"potentialAction": {
|
|
1057
|
+
"@type": "SearchAction",
|
|
1058
|
+
"target": `${config.url}/search?q={search_term_string}`,
|
|
1059
|
+
"query-input": "required name=search_term_string"
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
if (props.type === "article") {
|
|
1063
|
+
schemas.push({
|
|
1064
|
+
"@context": "https://schema.org",
|
|
1065
|
+
"@type": "NewsArticle",
|
|
1066
|
+
"headline": props.title || config.name,
|
|
1067
|
+
"description": description,
|
|
1068
|
+
"image": image,
|
|
1069
|
+
"datePublished": props.publishedTime,
|
|
1070
|
+
"dateModified": props.modifiedTime || props.publishedTime,
|
|
1071
|
+
"author": props.author ? {
|
|
1072
|
+
"@type": "Person",
|
|
1073
|
+
"name": props.author.name,
|
|
1074
|
+
"url": props.author.url
|
|
1075
|
+
} : organizationSchema,
|
|
1076
|
+
"publisher": organizationSchema,
|
|
1077
|
+
"wordCount": props.readingTime ? (props.readingTime * 200).toString() : void 0
|
|
1078
|
+
// Mock calculation
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
if (props.type === "product" && props.product) {
|
|
1082
|
+
schemas.push({
|
|
1083
|
+
"@context": "https://schema.org",
|
|
1084
|
+
"@type": "Product",
|
|
1085
|
+
"name": props.title,
|
|
1086
|
+
"image": image,
|
|
1087
|
+
"description": description,
|
|
1088
|
+
"sku": props.product.sku,
|
|
1089
|
+
"brand": {
|
|
1090
|
+
"@type": "Brand",
|
|
1091
|
+
"name": props.product.brand
|
|
1092
|
+
},
|
|
1093
|
+
"offers": {
|
|
1094
|
+
"@type": "Offer",
|
|
1095
|
+
"url": url,
|
|
1096
|
+
"priceCurrency": props.product.currency || "USD",
|
|
1097
|
+
"price": props.product.price,
|
|
1098
|
+
"availability": props.product.availability || "https://schema.org/InStock"
|
|
1099
|
+
},
|
|
1100
|
+
"aggregateRating": props.product.rating ? {
|
|
1101
|
+
"@type": "AggregateRating",
|
|
1102
|
+
"ratingValue": props.product.rating,
|
|
1103
|
+
"reviewCount": props.product.reviewCount || 1
|
|
1104
|
+
} : void 0
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
if (props.schema) {
|
|
1108
|
+
if (Array.isArray(props.schema)) {
|
|
1109
|
+
schemas.push(...props.schema);
|
|
1110
|
+
} else {
|
|
1111
|
+
schemas.push(props.schema);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Helmet, { children: [
|
|
1115
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("title", { children: title }),
|
|
1116
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "description", content: description }),
|
|
1117
|
+
props.keywords && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "keywords", content: props.keywords.join(", ") }),
|
|
1118
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "robots", content: props.noindex ? "noindex, nofollow" : props.robots || "index, follow" }),
|
|
1119
|
+
!props.noindex && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "canonical", href: url }),
|
|
1120
|
+
props.prev && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "prev", href: props.prev }),
|
|
1121
|
+
props.next && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "next", href: props.next }),
|
|
1122
|
+
config.language && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { httpEquiv: "content-language", content: config.language }),
|
|
1123
|
+
props.alternates?.map((alt, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "alternate", hrefLang: alt.hreflang, href: alt.href }, i)),
|
|
1124
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:type", content: props.ogType || (props.type === "article" ? "article" : "website") }),
|
|
1125
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:title", content: props.ogTitle || title }),
|
|
1126
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:description", content: props.ogDescription || description }),
|
|
1127
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:image", content: props.ogImage || image }),
|
|
1128
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:url", content: url }),
|
|
1129
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:site_name", content: config.name }),
|
|
1130
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:locale", content: props.ogLocale || config.language || "en_US" }),
|
|
1131
|
+
config.facebookAppId && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "fb:app_id", content: config.facebookAppId }),
|
|
1132
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:card", content: props.twitterCard || "summary_large_image" }),
|
|
1133
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:title", content: props.twitterTitle || title }),
|
|
1134
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:description", content: props.twitterDescription || description }),
|
|
1135
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:image", content: props.twitterImage || image }),
|
|
1136
|
+
config.twitterHandle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:site", content: config.twitterHandle }),
|
|
1137
|
+
config.twitterHandle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:creator", content: config.twitterHandle }),
|
|
1138
|
+
props.readingTime && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:label1", content: "Reading time" }),
|
|
1139
|
+
props.readingTime && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:data1", content: `${props.readingTime} min` }),
|
|
1140
|
+
props.type === "article" && props.publishedTime && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "article:published_time", content: props.publishedTime }),
|
|
1141
|
+
props.type === "article" && props.modifiedTime && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "article:modified_time", content: props.modifiedTime }),
|
|
1142
|
+
props.type === "article" && props.section && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "article:section", content: props.section }),
|
|
1143
|
+
props.type === "article" && props.tags?.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "article:tag", content: tag }, tag)),
|
|
1144
|
+
config.themeColor && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "theme-color", content: config.themeColor }),
|
|
1145
|
+
config.manifest && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "manifest", href: config.manifest }),
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "apple-mobile-web-app-capable", content: "yes" }),
|
|
1147
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "apple-mobile-web-app-status-bar-style", content: "default" }),
|
|
1148
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "apple-mobile-web-app-title", content: config.name }),
|
|
1149
|
+
props.dnsPrefetch?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "dns-prefetch", href: d }, d)),
|
|
1150
|
+
props.preconnect?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "preconnect", href: d }, d)),
|
|
1151
|
+
props.prefetch?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "prefetch", href: d }, d)),
|
|
1152
|
+
props.preload?.map((p) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "preload", href: p.href, as: p.as, type: p.type }, p.href)),
|
|
1153
|
+
(props.whatsappImage || image) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:image:secure_url", content: props.whatsappImage || image }),
|
|
1154
|
+
props.whatsappDescription && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "whatsapp:description", content: props.whatsappDescription }),
|
|
1155
|
+
config.googleAnalyticsId && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("script", { async: true, src: `https://www.googletagmanager.com/gtag/js?id=${config.googleAnalyticsId}` }),
|
|
1156
|
+
config.googleAnalyticsId && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("script", { children: `window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '${config.googleAnalyticsId}');` }),
|
|
1157
|
+
schemas.map((schema, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }, index)),
|
|
1158
|
+
props.children
|
|
1159
|
+
] });
|
|
1160
|
+
};
|
|
1161
|
+
|
|
1162
|
+
// src/components/Breadcrumb.tsx
|
|
1163
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1164
|
+
var Breadcrumb = ({
|
|
1165
|
+
items,
|
|
1166
|
+
className = "breadcrumb",
|
|
1167
|
+
separator = " / ",
|
|
1168
|
+
renderLink
|
|
1169
|
+
}) => {
|
|
1170
|
+
const schema = {
|
|
1171
|
+
"@context": "https://schema.org",
|
|
1172
|
+
"@type": "BreadcrumbList",
|
|
1173
|
+
"itemListElement": items.map((item, index) => ({
|
|
1174
|
+
"@type": "ListItem",
|
|
1175
|
+
"position": index + 1,
|
|
1176
|
+
"name": item.name,
|
|
1177
|
+
"item": item.item
|
|
1178
|
+
}))
|
|
1179
|
+
};
|
|
1180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1181
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) }),
|
|
1182
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("nav", { className, "aria-label": "Breadcrumb", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { style: { display: "flex", listStyle: "none", padding: 0 }, children: items.map((item, index) => {
|
|
1183
|
+
const isLast = index === items.length - 1;
|
|
1184
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { style: { display: "flex", alignItems: "center" }, children: [
|
|
1185
|
+
renderLink ? renderLink(item, isLast) : isLast ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-current": "page", children: item.name }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: item.item, children: item.name }),
|
|
1186
|
+
!isLast && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { margin: "0 8px" }, children: separator })
|
|
1187
|
+
] }, index);
|
|
1188
|
+
}) }) })
|
|
1189
|
+
] });
|
|
1190
|
+
};
|
|
1191
|
+
|
|
1192
|
+
// src/components/SeoArticle.tsx
|
|
1193
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1194
|
+
var SeoArticle = ({ article, ...rest }) => {
|
|
1195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1196
|
+
SEO,
|
|
1197
|
+
{
|
|
1198
|
+
type: "article",
|
|
1199
|
+
title: article.title,
|
|
1200
|
+
description: article.description,
|
|
1201
|
+
image: article.image,
|
|
1202
|
+
publishedTime: article.publishedAt,
|
|
1203
|
+
modifiedTime: article.updatedAt,
|
|
1204
|
+
author: article.author,
|
|
1205
|
+
section: article.category,
|
|
1206
|
+
tags: article.tags,
|
|
1207
|
+
...rest
|
|
1208
|
+
}
|
|
1209
|
+
);
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1212
|
+
// src/components/SeoProduct.tsx
|
|
1213
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1214
|
+
var SeoProduct = ({ item, ...rest }) => {
|
|
1215
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1216
|
+
SEO,
|
|
1217
|
+
{
|
|
1218
|
+
type: "product",
|
|
1219
|
+
title: item.name,
|
|
1220
|
+
description: item.description,
|
|
1221
|
+
image: item.image,
|
|
1222
|
+
product: {
|
|
1223
|
+
sku: item.sku,
|
|
1224
|
+
brand: item.brand,
|
|
1225
|
+
price: item.price,
|
|
1226
|
+
currency: item.currency,
|
|
1227
|
+
availability: item.availability,
|
|
1228
|
+
rating: item.rating,
|
|
1229
|
+
reviewCount: item.reviewCount
|
|
1230
|
+
},
|
|
1231
|
+
...rest
|
|
1232
|
+
}
|
|
1233
|
+
);
|
|
1234
|
+
};
|
|
1235
|
+
|
|
1236
|
+
// src/components/SeoFAQ.tsx
|
|
1237
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1238
|
+
var SeoFAQ = ({ items }) => {
|
|
1239
|
+
const schema = {
|
|
1240
|
+
"@context": "https://schema.org",
|
|
1241
|
+
"@type": "FAQPage",
|
|
1242
|
+
"mainEntity": items.map((item) => ({
|
|
1243
|
+
"@type": "Question",
|
|
1244
|
+
"name": item.question,
|
|
1245
|
+
"acceptedAnswer": {
|
|
1246
|
+
"@type": "Answer",
|
|
1247
|
+
"text": item.answer
|
|
1248
|
+
}
|
|
1249
|
+
}))
|
|
1250
|
+
};
|
|
1251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
1252
|
+
};
|
|
1253
|
+
|
|
1254
|
+
// src/components/SeoVideo.tsx
|
|
1255
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1256
|
+
var SeoVideo = ({ video }) => {
|
|
1257
|
+
const schema = {
|
|
1258
|
+
"@context": "https://schema.org",
|
|
1259
|
+
"@type": "VideoObject",
|
|
1260
|
+
"name": video.name,
|
|
1261
|
+
"description": video.description,
|
|
1262
|
+
"thumbnailUrl": Array.isArray(video.thumbnailUrl) ? video.thumbnailUrl : [video.thumbnailUrl],
|
|
1263
|
+
"uploadDate": video.uploadDate,
|
|
1264
|
+
"contentUrl": video.contentUrl,
|
|
1265
|
+
"embedUrl": video.embedUrl,
|
|
1266
|
+
"duration": video.duration,
|
|
1267
|
+
"interactionStatistic": video.interactionStatistic ? {
|
|
1268
|
+
"@type": "InteractionCounter",
|
|
1269
|
+
"interactionType": "https://schema.org/WatchAction",
|
|
1270
|
+
"userInteractionCount": video.interactionStatistic.viewCount
|
|
1271
|
+
} : void 0
|
|
1272
|
+
};
|
|
1273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
1274
|
+
};
|
|
1275
|
+
|
|
1276
|
+
// src/components/SeoEvent.tsx
|
|
1277
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1278
|
+
var SeoEvent = ({ event }) => {
|
|
1279
|
+
const schema = {
|
|
1280
|
+
"@context": "https://schema.org",
|
|
1281
|
+
"@type": "Event",
|
|
1282
|
+
"name": event.name,
|
|
1283
|
+
"description": event.description,
|
|
1284
|
+
"startDate": event.startDate,
|
|
1285
|
+
"endDate": event.endDate,
|
|
1286
|
+
"eventStatus": event.eventStatus ? `https://schema.org/${event.eventStatus}` : void 0,
|
|
1287
|
+
"eventAttendanceMode": event.eventAttendanceMode ? `https://schema.org/${event.eventAttendanceMode}` : void 0,
|
|
1288
|
+
"location": event.eventAttendanceMode === "OnlineEventAttendanceMode" ? {
|
|
1289
|
+
"@type": "VirtualLocation",
|
|
1290
|
+
"url": event.location.url
|
|
1291
|
+
} : {
|
|
1292
|
+
"@type": "Place",
|
|
1293
|
+
"name": event.location.name,
|
|
1294
|
+
"address": {
|
|
1295
|
+
"@type": "PostalAddress",
|
|
1296
|
+
"streetAddress": event.location.address
|
|
1297
|
+
}
|
|
1298
|
+
},
|
|
1299
|
+
"image": Array.isArray(event.image) ? event.image : event.image ? [event.image] : void 0,
|
|
1300
|
+
"offers": event.offers ? {
|
|
1301
|
+
"@type": "Offer",
|
|
1302
|
+
"price": event.offers.price,
|
|
1303
|
+
"priceCurrency": event.offers.priceCurrency,
|
|
1304
|
+
"url": event.offers.url,
|
|
1305
|
+
"availability": event.offers.availability || "https://schema.org/InStock"
|
|
1306
|
+
} : void 0,
|
|
1307
|
+
"organizer": event.organizer ? {
|
|
1308
|
+
"@type": "Organization",
|
|
1309
|
+
"name": event.organizer.name,
|
|
1310
|
+
"url": event.organizer.url
|
|
1311
|
+
} : void 0
|
|
1312
|
+
};
|
|
1313
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
// src/components/SeoLocalBusiness.tsx
|
|
1317
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1318
|
+
var SeoLocalBusiness = ({ business }) => {
|
|
1319
|
+
const schema = {
|
|
1320
|
+
"@context": "https://schema.org",
|
|
1321
|
+
"@type": business.type || "LocalBusiness",
|
|
1322
|
+
"@id": business.id || business.url,
|
|
1323
|
+
"name": business.name,
|
|
1324
|
+
"image": Array.isArray(business.image) ? business.image : business.image ? [business.image] : void 0,
|
|
1325
|
+
"description": business.description,
|
|
1326
|
+
"url": business.url,
|
|
1327
|
+
"telephone": business.telephone,
|
|
1328
|
+
"priceRange": business.priceRange,
|
|
1329
|
+
"address": {
|
|
1330
|
+
"@type": "PostalAddress",
|
|
1331
|
+
"streetAddress": business.address.streetAddress,
|
|
1332
|
+
"addressLocality": business.address.addressLocality,
|
|
1333
|
+
"addressRegion": business.address.addressRegion,
|
|
1334
|
+
"postalCode": business.address.postalCode,
|
|
1335
|
+
"addressCountry": business.address.addressCountry
|
|
1336
|
+
},
|
|
1337
|
+
"geo": business.geo ? {
|
|
1338
|
+
"@type": "GeoCoordinates",
|
|
1339
|
+
"latitude": business.geo.latitude,
|
|
1340
|
+
"longitude": business.geo.longitude
|
|
1341
|
+
} : void 0,
|
|
1342
|
+
"openingHours": business.openingHours
|
|
1343
|
+
};
|
|
1344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
// src/components/SeoCategory.tsx
|
|
1348
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1349
|
+
var SeoCategory = ({ category, page = 1, totalPage = 1, ...rest }) => {
|
|
1350
|
+
const hasNext = page < totalPage;
|
|
1351
|
+
const hasPrev = page > 1;
|
|
1352
|
+
const baseUrl = category.url.split("?")[0];
|
|
1353
|
+
const nextUrl = hasNext ? `${baseUrl}?page=${page + 1}` : void 0;
|
|
1354
|
+
const prevUrl = hasPrev ? page === 2 ? baseUrl : `${baseUrl}?page=${page - 1}` : void 0;
|
|
1355
|
+
const canonical = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
|
|
1356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1357
|
+
SEO,
|
|
1358
|
+
{
|
|
1359
|
+
type: "website",
|
|
1360
|
+
title: `${category.name}${page > 1 ? ` - \u0635\u0641\u062D\u0629 ${page}` : ""}`,
|
|
1361
|
+
description: category.description,
|
|
1362
|
+
image: category.image,
|
|
1363
|
+
canonical,
|
|
1364
|
+
next: nextUrl,
|
|
1365
|
+
prev: prevUrl,
|
|
1366
|
+
schema: {
|
|
1367
|
+
"@context": "https://schema.org",
|
|
1368
|
+
"@type": "CollectionPage",
|
|
1369
|
+
"name": category.name,
|
|
1370
|
+
"description": category.description,
|
|
1371
|
+
"url": canonical
|
|
1372
|
+
},
|
|
1373
|
+
...rest
|
|
1374
|
+
}
|
|
1375
|
+
);
|
|
1376
|
+
};
|
|
1377
|
+
|
|
1378
|
+
// src/components/SeoTag.tsx
|
|
1379
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1380
|
+
var SeoTag = ({ tag, page = 1, totalPage = 1, ...rest }) => {
|
|
1381
|
+
const hasNext = page < totalPage;
|
|
1382
|
+
const hasPrev = page > 1;
|
|
1383
|
+
const baseUrl = tag.url.split("?")[0];
|
|
1384
|
+
const nextUrl = hasNext ? `${baseUrl}?page=${page + 1}` : void 0;
|
|
1385
|
+
const prevUrl = hasPrev ? page === 2 ? baseUrl : `${baseUrl}?page=${page - 1}` : void 0;
|
|
1386
|
+
const canonical = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
|
|
1387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1388
|
+
SEO,
|
|
1389
|
+
{
|
|
1390
|
+
type: "website",
|
|
1391
|
+
title: `\u062A\u0627\u063A: ${tag.name}${page > 1 ? ` - \u0635\u0641\u062D\u0629 ${page}` : ""}`,
|
|
1392
|
+
description: tag.description || `\u0643\u0644 \u0627\u0644\u0645\u0642\u0627\u0644\u0627\u062A \u0627\u0644\u0645\u062A\u0639\u0644\u0642\u0629 \u0628\u0640 ${tag.name}`,
|
|
1393
|
+
canonical,
|
|
1394
|
+
next: nextUrl,
|
|
1395
|
+
prev: prevUrl,
|
|
1396
|
+
...rest
|
|
1397
|
+
}
|
|
1398
|
+
);
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1401
|
+
// src/components/SeoAuthor.tsx
|
|
1402
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1403
|
+
var SeoAuthor = ({ author, page = 1, totalPage = 1, ...rest }) => {
|
|
1404
|
+
const hasNext = page < totalPage;
|
|
1405
|
+
const hasPrev = page > 1;
|
|
1406
|
+
const baseUrl = author.url.split("?")[0];
|
|
1407
|
+
const nextUrl = hasNext ? `${baseUrl}?page=${page + 1}` : void 0;
|
|
1408
|
+
const prevUrl = hasPrev ? page === 2 ? baseUrl : `${baseUrl}?page=${page - 1}` : void 0;
|
|
1409
|
+
const canonical = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
|
|
1410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1411
|
+
SEO,
|
|
1412
|
+
{
|
|
1413
|
+
type: "profile",
|
|
1414
|
+
title: `${author.name}${page > 1 ? ` - \u0635\u0641\u062D\u0629 ${page}` : ""}`,
|
|
1415
|
+
description: author.description,
|
|
1416
|
+
image: author.image,
|
|
1417
|
+
canonical,
|
|
1418
|
+
next: nextUrl,
|
|
1419
|
+
prev: prevUrl,
|
|
1420
|
+
schema: {
|
|
1421
|
+
"@context": "https://schema.org",
|
|
1422
|
+
"@type": "Person",
|
|
1423
|
+
"name": author.name,
|
|
1424
|
+
"description": author.description,
|
|
1425
|
+
"image": author.image,
|
|
1426
|
+
"jobTitle": author.jobTitle,
|
|
1427
|
+
"url": canonical
|
|
1428
|
+
},
|
|
1429
|
+
...rest
|
|
1430
|
+
}
|
|
1431
|
+
);
|
|
1432
|
+
};
|
|
1433
|
+
|
|
1434
|
+
// src/components/SeoHowTo.tsx
|
|
1435
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1436
|
+
var SeoHowTo = ({ name, description, image, steps }) => {
|
|
1437
|
+
const schema = {
|
|
1438
|
+
"@context": "https://schema.org",
|
|
1439
|
+
"@type": "HowTo",
|
|
1440
|
+
"name": name,
|
|
1441
|
+
"description": description,
|
|
1442
|
+
"image": image,
|
|
1443
|
+
"step": steps.map((step, index) => {
|
|
1444
|
+
if (typeof step === "string") {
|
|
1445
|
+
return {
|
|
1446
|
+
"@type": "HowToStep",
|
|
1447
|
+
"position": index + 1,
|
|
1448
|
+
"text": step
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
return {
|
|
1452
|
+
"@type": "HowToStep",
|
|
1453
|
+
"position": index + 1,
|
|
1454
|
+
"name": step.name,
|
|
1455
|
+
"text": step.text,
|
|
1456
|
+
"image": step.image,
|
|
1457
|
+
"url": step.url
|
|
1458
|
+
};
|
|
1459
|
+
})
|
|
1460
|
+
};
|
|
1461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
1462
|
+
};
|
|
1463
|
+
|
|
1464
|
+
// src/components/SeoReview.tsx
|
|
1465
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1466
|
+
var SeoReview = ({ itemReviewed, review }) => {
|
|
1467
|
+
const schema = {
|
|
1468
|
+
"@context": "https://schema.org",
|
|
1469
|
+
"@type": "Review",
|
|
1470
|
+
"itemReviewed": {
|
|
1471
|
+
"@type": itemReviewed.type,
|
|
1472
|
+
"name": itemReviewed.name,
|
|
1473
|
+
"image": itemReviewed.image
|
|
1474
|
+
},
|
|
1475
|
+
"author": {
|
|
1476
|
+
"@type": "Person",
|
|
1477
|
+
"name": review.author
|
|
1478
|
+
},
|
|
1479
|
+
"datePublished": review.datePublished,
|
|
1480
|
+
"reviewBody": review.reviewBody,
|
|
1481
|
+
"reviewRating": {
|
|
1482
|
+
"@type": "Rating",
|
|
1483
|
+
"ratingValue": review.ratingValue,
|
|
1484
|
+
"bestRating": review.bestRating || 5,
|
|
1485
|
+
"worstRating": review.worstRating || 1
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
1489
|
+
};
|
|
1490
|
+
|
|
1491
|
+
// src/components/SeoCourse.tsx
|
|
1492
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1493
|
+
var SeoCourse = ({ course }) => {
|
|
1494
|
+
const schema = {
|
|
1495
|
+
"@context": "https://schema.org",
|
|
1496
|
+
"@type": "Course",
|
|
1497
|
+
"name": course.name,
|
|
1498
|
+
"description": course.description,
|
|
1499
|
+
"provider": {
|
|
1500
|
+
"@type": "Organization",
|
|
1501
|
+
"name": course.providerName,
|
|
1502
|
+
"sameAs": course.providerUrl
|
|
1503
|
+
},
|
|
1504
|
+
"image": course.image
|
|
1505
|
+
};
|
|
1506
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
1507
|
+
};
|
|
1508
|
+
|
|
1509
|
+
// src/components/SeoRecipe.tsx
|
|
1510
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1511
|
+
var SeoRecipe = ({ recipe }) => {
|
|
1512
|
+
const schema = {
|
|
1513
|
+
"@context": "https://schema.org",
|
|
1514
|
+
"@type": "Recipe",
|
|
1515
|
+
"name": recipe.name,
|
|
1516
|
+
"description": recipe.description,
|
|
1517
|
+
"image": recipe.image,
|
|
1518
|
+
"author": {
|
|
1519
|
+
"@type": "Person",
|
|
1520
|
+
"name": recipe.author
|
|
1521
|
+
},
|
|
1522
|
+
"datePublished": recipe.publishedDate,
|
|
1523
|
+
"prepTime": recipe.prepTime,
|
|
1524
|
+
"cookTime": recipe.cookTime,
|
|
1525
|
+
"totalTime": recipe.totalTime,
|
|
1526
|
+
"recipeYield": recipe.recipeYield,
|
|
1527
|
+
"recipeCategory": recipe.recipeCategory,
|
|
1528
|
+
"recipeCuisine": recipe.recipeCuisine,
|
|
1529
|
+
"recipeIngredient": recipe.ingredients,
|
|
1530
|
+
"recipeInstructions": recipe.instructions.map((step) => ({
|
|
1531
|
+
"@type": "HowToStep",
|
|
1532
|
+
"name": step.name,
|
|
1533
|
+
"text": step.text,
|
|
1534
|
+
"image": step.image
|
|
1535
|
+
}))
|
|
1536
|
+
};
|
|
1537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
1538
|
+
};
|
|
1539
|
+
|
|
1540
|
+
// src/components/SeoJobPosting.tsx
|
|
1541
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1542
|
+
var SeoJobPosting = ({ job }) => {
|
|
1543
|
+
const schema = {
|
|
1544
|
+
"@context": "https://schema.org",
|
|
1545
|
+
"@type": "JobPosting",
|
|
1546
|
+
"title": job.title,
|
|
1547
|
+
"description": job.description,
|
|
1548
|
+
"datePosted": job.datePosted,
|
|
1549
|
+
"validThrough": job.validThrough,
|
|
1550
|
+
"employmentType": job.employmentType,
|
|
1551
|
+
"hiringOrganization": {
|
|
1552
|
+
"@type": "Organization",
|
|
1553
|
+
"name": job.hiringOrganization.name,
|
|
1554
|
+
"sameAs": job.hiringOrganization.sameAs,
|
|
1555
|
+
"logo": job.hiringOrganization.logo
|
|
1556
|
+
},
|
|
1557
|
+
"jobLocation": {
|
|
1558
|
+
"@type": "Place",
|
|
1559
|
+
"address": {
|
|
1560
|
+
"@type": "PostalAddress",
|
|
1561
|
+
"streetAddress": job.jobLocation.streetAddress,
|
|
1562
|
+
"addressLocality": job.jobLocation.addressLocality,
|
|
1563
|
+
"addressRegion": job.jobLocation.addressRegion,
|
|
1564
|
+
"postalCode": job.jobLocation.postalCode,
|
|
1565
|
+
"addressCountry": job.jobLocation.addressCountry
|
|
1566
|
+
}
|
|
1567
|
+
},
|
|
1568
|
+
"baseSalary": job.baseSalary ? {
|
|
1569
|
+
"@type": "MonetaryAmount",
|
|
1570
|
+
"currency": job.baseSalary.currency,
|
|
1571
|
+
"value": typeof job.baseSalary.value === "number" ? {
|
|
1572
|
+
"@type": "QuantitativeValue",
|
|
1573
|
+
"value": job.baseSalary.value,
|
|
1574
|
+
"unitText": job.baseSalary.unitText || "MONTH"
|
|
1575
|
+
} : {
|
|
1576
|
+
"@type": "QuantitativeValue",
|
|
1577
|
+
"minValue": job.baseSalary.value.minValue,
|
|
1578
|
+
"maxValue": job.baseSalary.value.maxValue,
|
|
1579
|
+
"unitText": job.baseSalary.unitText || "MONTH"
|
|
1580
|
+
}
|
|
1581
|
+
} : void 0
|
|
1582
|
+
};
|
|
1583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
1584
|
+
};
|
|
1585
|
+
|
|
1586
|
+
// src/utils/next-adapter.ts
|
|
1587
|
+
function toNextMetadata(props, config) {
|
|
1588
|
+
const title = props.title ? `${props.title} | ${config.name}` : config.name;
|
|
1589
|
+
const description = props.description || config.description;
|
|
1590
|
+
const url = props.canonical || config.url;
|
|
1591
|
+
const image = props.image || config.logo;
|
|
1592
|
+
const metadata = {
|
|
1593
|
+
title,
|
|
1594
|
+
description,
|
|
1595
|
+
keywords: props.keywords,
|
|
1596
|
+
robots: props.noindex ? "noindex, nofollow" : props.robots || "index, follow",
|
|
1597
|
+
alternates: {
|
|
1598
|
+
canonical: props.noindex ? void 0 : url
|
|
1599
|
+
},
|
|
1600
|
+
openGraph: {
|
|
1601
|
+
title: props.ogTitle || title,
|
|
1602
|
+
description: props.ogDescription || description,
|
|
1603
|
+
url,
|
|
1604
|
+
siteName: config.name,
|
|
1605
|
+
images: props.ogImage || image ? [{ url: props.ogImage || image }] : [],
|
|
1606
|
+
type: props.ogType || (props.type === "article" ? "article" : "website"),
|
|
1607
|
+
locale: props.ogLocale || config.language || "ar_SA"
|
|
1608
|
+
},
|
|
1609
|
+
twitter: {
|
|
1610
|
+
card: props.twitterCard || "summary_large_image",
|
|
1611
|
+
title: props.twitterTitle || title,
|
|
1612
|
+
description: props.twitterDescription || description,
|
|
1613
|
+
images: props.twitterImage || image ? [props.twitterImage || image] : [],
|
|
1614
|
+
site: config.twitterHandle,
|
|
1615
|
+
creator: config.twitterHandle
|
|
1616
|
+
},
|
|
1617
|
+
other: {}
|
|
1618
|
+
};
|
|
1619
|
+
if (props.alternates && props.alternates.length > 0) {
|
|
1620
|
+
const languages = {};
|
|
1621
|
+
props.alternates.forEach((alt) => {
|
|
1622
|
+
languages[alt.hreflang] = alt.href;
|
|
1623
|
+
});
|
|
1624
|
+
metadata.alternates.languages = languages;
|
|
1625
|
+
}
|
|
1626
|
+
metadata.appleWebApp = {
|
|
1627
|
+
capable: true,
|
|
1628
|
+
title: config.name,
|
|
1629
|
+
statusBarStyle: "default"
|
|
1630
|
+
};
|
|
1631
|
+
if (props.dnsPrefetch) metadata.other["dns-prefetch"] = props.dnsPrefetch;
|
|
1632
|
+
if (config.themeColor) metadata.themeColor = config.themeColor;
|
|
1633
|
+
if (config.manifest) metadata.manifest = config.manifest;
|
|
1634
|
+
return metadata;
|
|
1635
|
+
}
|
|
1636
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1637
|
+
0 && (module.exports = {
|
|
1638
|
+
Breadcrumb,
|
|
1639
|
+
SEO,
|
|
1640
|
+
SEOProvider,
|
|
1641
|
+
SeoArticle,
|
|
1642
|
+
SeoAuthor,
|
|
1643
|
+
SeoCategory,
|
|
1644
|
+
SeoCourse,
|
|
1645
|
+
SeoEvent,
|
|
1646
|
+
SeoFAQ,
|
|
1647
|
+
SeoHowTo,
|
|
1648
|
+
SeoJobPosting,
|
|
1649
|
+
SeoLocalBusiness,
|
|
1650
|
+
SeoProduct,
|
|
1651
|
+
SeoRecipe,
|
|
1652
|
+
SeoReview,
|
|
1653
|
+
SeoTag,
|
|
1654
|
+
SeoVideo,
|
|
1655
|
+
toNextMetadata,
|
|
1656
|
+
useSEOConfig
|
|
1657
|
+
});
|