@masters-ws/react-seo 1.2.1 → 1.4.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/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/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 +794 -129
- package/dist/index.mjs +57 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
Breadcrumb: () => Breadcrumb,
|
|
24
|
+
JsonLd: () => JsonLd,
|
|
24
25
|
SEO: () => SEO,
|
|
25
26
|
SEOProvider: () => SEOProvider,
|
|
26
27
|
SeoArticle: () => SeoArticle,
|
|
@@ -37,11 +38,19 @@ __export(index_exports, {
|
|
|
37
38
|
SeoReview: () => SeoReview,
|
|
38
39
|
SeoTag: () => SeoTag,
|
|
39
40
|
SeoVideo: () => SeoVideo,
|
|
41
|
+
cleanSchema: () => cleanSchema,
|
|
42
|
+
generateArticleMetadata: () => generateArticleMetadata,
|
|
40
43
|
generateArticleSchema: () => generateArticleSchema,
|
|
41
44
|
generateBookSchema: () => generateBookSchema,
|
|
42
45
|
generateBreadcrumbSchema: () => generateBreadcrumbSchema,
|
|
46
|
+
generateCategoryMetadata: () => generateCategoryMetadata,
|
|
47
|
+
generateCollectionPageSchema: () => generateCollectionPageSchema,
|
|
43
48
|
generateEventSchema: () => generateEventSchema,
|
|
44
49
|
generateFAQSchema: () => generateFAQSchema,
|
|
50
|
+
generateHomepageMetadata: () => generateHomepageMetadata,
|
|
51
|
+
generateHowToSchema: () => generateHowToSchema,
|
|
52
|
+
generateItemListSchema: () => generateItemListSchema,
|
|
53
|
+
generateJobPostingSchema: () => generateJobPostingSchema,
|
|
45
54
|
generateLocalBusinessSchema: () => generateLocalBusinessSchema,
|
|
46
55
|
generateMovieSchema: () => generateMovieSchema,
|
|
47
56
|
generateOrganizationSchema: () => generateOrganizationSchema,
|
|
@@ -49,83 +58,267 @@ __export(index_exports, {
|
|
|
49
58
|
generatePaginationLinks: () => generatePaginationLinks,
|
|
50
59
|
generatePodcastEpisodeSchema: () => generatePodcastEpisodeSchema,
|
|
51
60
|
generatePodcastSchema: () => generatePodcastSchema,
|
|
61
|
+
generateProductMetadata: () => generateProductMetadata,
|
|
52
62
|
generateProductSchema: () => generateProductSchema,
|
|
63
|
+
generateRecipeSchema: () => generateRecipeSchema,
|
|
53
64
|
generateSoftwareSchema: () => generateSoftwareSchema,
|
|
54
65
|
generateVideoSchema: () => generateVideoSchema,
|
|
66
|
+
generateWebPageSchema: () => generateWebPageSchema,
|
|
55
67
|
generateWebSiteSchema: () => generateWebSiteSchema,
|
|
56
68
|
toNextMetadata: () => toNextMetadata,
|
|
57
|
-
useSEOConfig: () => useSEOConfig
|
|
69
|
+
useSEOConfig: () => useSEOConfig,
|
|
70
|
+
validateSEO: () => validateSEO
|
|
58
71
|
});
|
|
59
72
|
module.exports = __toCommonJS(index_exports);
|
|
60
73
|
|
|
74
|
+
// src/core/utils.ts
|
|
75
|
+
function cleanSchema(obj) {
|
|
76
|
+
if (Array.isArray(obj)) {
|
|
77
|
+
return obj.filter((item) => item !== void 0 && item !== null).map((item) => typeof item === "object" ? cleanSchema(item) : item);
|
|
78
|
+
}
|
|
79
|
+
const cleaned = {};
|
|
80
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
81
|
+
if (value === void 0 || value === null) continue;
|
|
82
|
+
if (Array.isArray(value)) {
|
|
83
|
+
const cleanedArr = value.filter((item) => item !== void 0 && item !== null).map((item) => typeof item === "object" && item !== null ? cleanSchema(item) : item);
|
|
84
|
+
if (cleanedArr.length > 0) {
|
|
85
|
+
cleaned[key] = cleanedArr;
|
|
86
|
+
}
|
|
87
|
+
} else if (typeof value === "object") {
|
|
88
|
+
cleaned[key] = cleanSchema(value);
|
|
89
|
+
} else {
|
|
90
|
+
cleaned[key] = value;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return cleaned;
|
|
94
|
+
}
|
|
95
|
+
function validateSEO(schemaType, data, requiredFields) {
|
|
96
|
+
const warnings = [];
|
|
97
|
+
for (const field of requiredFields) {
|
|
98
|
+
const value = data[field];
|
|
99
|
+
if (value === void 0 || value === null || value === "") {
|
|
100
|
+
warnings.push(`[react-seo] Warning: "${field}" is missing in ${schemaType} schema. Google may not show rich results.`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (warnings.length > 0 && typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV !== "production") {
|
|
104
|
+
warnings.forEach((w) => console.warn(w));
|
|
105
|
+
}
|
|
106
|
+
return warnings;
|
|
107
|
+
}
|
|
108
|
+
|
|
61
109
|
// src/core/schemas.ts
|
|
62
110
|
function generateOrganizationSchema(config) {
|
|
63
|
-
return {
|
|
111
|
+
return cleanSchema({
|
|
64
112
|
"@context": "https://schema.org",
|
|
65
113
|
"@type": "Organization",
|
|
66
114
|
"name": config.name,
|
|
67
115
|
"url": config.url,
|
|
68
116
|
"logo": config.logo,
|
|
117
|
+
"description": config.description,
|
|
69
118
|
"sameAs": config.socialLinks || []
|
|
70
|
-
};
|
|
119
|
+
});
|
|
71
120
|
}
|
|
72
121
|
function generateWebSiteSchema(config) {
|
|
73
|
-
return {
|
|
122
|
+
return cleanSchema({
|
|
74
123
|
"@context": "https://schema.org",
|
|
75
124
|
"@type": "WebSite",
|
|
76
125
|
"name": config.name,
|
|
77
126
|
"url": config.url,
|
|
127
|
+
"description": config.description,
|
|
128
|
+
"publisher": {
|
|
129
|
+
"@type": "Organization",
|
|
130
|
+
"name": config.name,
|
|
131
|
+
"logo": config.logo
|
|
132
|
+
},
|
|
78
133
|
"potentialAction": {
|
|
79
134
|
"@type": "SearchAction",
|
|
80
135
|
"target": `${config.url}/search?q={search_term_string}`,
|
|
81
136
|
"query-input": "required name=search_term_string"
|
|
82
137
|
}
|
|
83
|
-
};
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function generateWebPageSchema(data, config) {
|
|
141
|
+
return cleanSchema({
|
|
142
|
+
"@context": "https://schema.org",
|
|
143
|
+
"@type": "WebPage",
|
|
144
|
+
"name": data.name,
|
|
145
|
+
"description": data.description,
|
|
146
|
+
"url": data.url,
|
|
147
|
+
"image": data.image,
|
|
148
|
+
"datePublished": data.datePublished,
|
|
149
|
+
"dateModified": data.dateModified,
|
|
150
|
+
"isPartOf": {
|
|
151
|
+
"@type": "WebSite",
|
|
152
|
+
"name": config.name,
|
|
153
|
+
"url": config.url
|
|
154
|
+
},
|
|
155
|
+
"breadcrumb": data.breadcrumb ? generateBreadcrumbSchema(data.breadcrumb) : void 0
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function generateCollectionPageSchema(data, config) {
|
|
159
|
+
return cleanSchema({
|
|
160
|
+
"@context": "https://schema.org",
|
|
161
|
+
"@type": "CollectionPage",
|
|
162
|
+
"name": data.name,
|
|
163
|
+
"description": data.description,
|
|
164
|
+
"url": data.url,
|
|
165
|
+
"image": data.image,
|
|
166
|
+
"numberOfItems": data.numberOfItems,
|
|
167
|
+
"isPartOf": {
|
|
168
|
+
"@type": "WebSite",
|
|
169
|
+
"name": config.name,
|
|
170
|
+
"url": config.url
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function generateItemListSchema(data) {
|
|
175
|
+
return cleanSchema({
|
|
176
|
+
"@context": "https://schema.org",
|
|
177
|
+
"@type": "ItemList",
|
|
178
|
+
"name": data.name,
|
|
179
|
+
"url": data.url,
|
|
180
|
+
"itemListOrder": data.itemListOrder === "ascending" ? "https://schema.org/ItemListOrderAscending" : data.itemListOrder === "descending" ? "https://schema.org/ItemListOrderDescending" : "https://schema.org/ItemListUnordered",
|
|
181
|
+
"numberOfItems": data.items.length,
|
|
182
|
+
"itemListElement": data.items.map((item, index) => ({
|
|
183
|
+
"@type": "ListItem",
|
|
184
|
+
"position": item.position || index + 1,
|
|
185
|
+
"name": item.name,
|
|
186
|
+
"url": item.url,
|
|
187
|
+
"image": item.image
|
|
188
|
+
}))
|
|
189
|
+
});
|
|
84
190
|
}
|
|
85
191
|
function generateArticleSchema(data, config) {
|
|
192
|
+
validateSEO("NewsArticle", data, ["title", "description", "image", "publishedTime", "author"]);
|
|
86
193
|
const org = generateOrganizationSchema(config);
|
|
87
|
-
return {
|
|
194
|
+
return cleanSchema({
|
|
88
195
|
"@context": "https://schema.org",
|
|
89
196
|
"@type": "NewsArticle",
|
|
90
197
|
"headline": data.title,
|
|
91
198
|
"description": data.description,
|
|
92
|
-
"image": data.image
|
|
199
|
+
"image": data.image,
|
|
93
200
|
"datePublished": data.publishedTime,
|
|
94
201
|
"dateModified": data.modifiedTime || data.publishedTime,
|
|
95
202
|
"mainEntityOfPage": data.url,
|
|
203
|
+
"wordCount": data.wordCount,
|
|
96
204
|
"author": data.author ? {
|
|
97
205
|
"@type": "Person",
|
|
98
206
|
"name": data.author.name,
|
|
99
207
|
"url": data.author.url
|
|
100
208
|
} : org,
|
|
101
209
|
"publisher": org
|
|
102
|
-
};
|
|
210
|
+
});
|
|
103
211
|
}
|
|
104
212
|
function generateProductSchema(data) {
|
|
105
|
-
|
|
213
|
+
validateSEO("Product", data, ["name", "description", "image", "price"]);
|
|
214
|
+
let offers;
|
|
215
|
+
if (data.variants && data.variants.length > 0) {
|
|
216
|
+
const prices = data.variants.map((v) => v.price);
|
|
217
|
+
offers = {
|
|
218
|
+
"@type": "AggregateOffer",
|
|
219
|
+
"lowPrice": Math.min(...prices),
|
|
220
|
+
"highPrice": Math.max(...prices),
|
|
221
|
+
"priceCurrency": data.currency || data.variants[0]?.currency || "USD",
|
|
222
|
+
"offerCount": data.variants.length,
|
|
223
|
+
"offers": data.variants.map((v) => cleanSchema({
|
|
224
|
+
"@type": "Offer",
|
|
225
|
+
"name": v.name,
|
|
226
|
+
"sku": v.sku,
|
|
227
|
+
"price": v.price,
|
|
228
|
+
"priceCurrency": v.currency || data.currency || "USD",
|
|
229
|
+
"availability": v.availability || data.availability || "https://schema.org/InStock",
|
|
230
|
+
"url": v.url || data.url,
|
|
231
|
+
"image": v.image,
|
|
232
|
+
"itemCondition": data.condition ? `https://schema.org/${data.condition}` : void 0
|
|
233
|
+
}))
|
|
234
|
+
};
|
|
235
|
+
} else {
|
|
236
|
+
offers = cleanSchema({
|
|
237
|
+
"@type": "Offer",
|
|
238
|
+
"url": data.url,
|
|
239
|
+
"priceCurrency": data.currency || "USD",
|
|
240
|
+
"price": data.price,
|
|
241
|
+
"availability": data.availability || "https://schema.org/InStock",
|
|
242
|
+
"itemCondition": data.condition ? `https://schema.org/${data.condition}` : void 0,
|
|
243
|
+
"seller": data.seller ? {
|
|
244
|
+
"@type": "Organization",
|
|
245
|
+
"name": data.seller.name,
|
|
246
|
+
"url": data.seller.url
|
|
247
|
+
} : void 0,
|
|
248
|
+
"hasMerchantReturnPolicy": data.returnPolicy ? cleanSchema({
|
|
249
|
+
"@type": "MerchantReturnPolicy",
|
|
250
|
+
"applicableCountry": data.shipping?.shippingDestination,
|
|
251
|
+
"returnPolicyCategory": data.returnPolicy.returnPolicyCategory ? `https://schema.org/${data.returnPolicy.returnPolicyCategory}` : "https://schema.org/MerchantReturnFiniteReturnWindow",
|
|
252
|
+
"merchantReturnDays": data.returnPolicy.returnWithin,
|
|
253
|
+
"returnMethod": data.returnPolicy.returnMethod ? `https://schema.org/${data.returnPolicy.returnMethod}` : void 0,
|
|
254
|
+
"returnFees": data.returnPolicy.returnFees ? `https://schema.org/${data.returnPolicy.returnFees}` : void 0
|
|
255
|
+
}) : void 0,
|
|
256
|
+
"shippingDetails": data.shipping ? cleanSchema({
|
|
257
|
+
"@type": "OfferShippingDetails",
|
|
258
|
+
"shippingRate": data.shipping.shippingRate ? {
|
|
259
|
+
"@type": "MonetaryAmount",
|
|
260
|
+
"value": data.shipping.shippingRate.value,
|
|
261
|
+
"currency": data.shipping.shippingRate.currency
|
|
262
|
+
} : void 0,
|
|
263
|
+
"shippingDestination": data.shipping.shippingDestination ? {
|
|
264
|
+
"@type": "DefinedRegion",
|
|
265
|
+
"addressCountry": data.shipping.shippingDestination
|
|
266
|
+
} : void 0,
|
|
267
|
+
"deliveryTime": data.shipping.deliveryTime ? {
|
|
268
|
+
"@type": "ShippingDeliveryTime",
|
|
269
|
+
"handlingTime": {
|
|
270
|
+
"@type": "QuantitativeValue",
|
|
271
|
+
"minValue": 0,
|
|
272
|
+
"maxValue": 1,
|
|
273
|
+
"unitCode": "DAY"
|
|
274
|
+
},
|
|
275
|
+
"transitTime": {
|
|
276
|
+
"@type": "QuantitativeValue",
|
|
277
|
+
"minValue": data.shipping.deliveryTime.minDays,
|
|
278
|
+
"maxValue": data.shipping.deliveryTime.maxDays,
|
|
279
|
+
"unitCode": "DAY"
|
|
280
|
+
}
|
|
281
|
+
} : void 0,
|
|
282
|
+
"freeShippingThreshold": data.shipping.freeShippingThreshold ? {
|
|
283
|
+
"@type": "MonetaryAmount",
|
|
284
|
+
"value": data.shipping.freeShippingThreshold,
|
|
285
|
+
"currency": data.shipping.shippingRate?.currency || data.currency || "USD"
|
|
286
|
+
} : void 0
|
|
287
|
+
}) : void 0
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
const reviewList = data.reviews?.map((r) => cleanSchema({
|
|
291
|
+
"@type": "Review",
|
|
292
|
+
"author": { "@type": "Person", "name": r.author },
|
|
293
|
+
"datePublished": r.datePublished,
|
|
294
|
+
"reviewBody": r.reviewBody,
|
|
295
|
+
"reviewRating": {
|
|
296
|
+
"@type": "Rating",
|
|
297
|
+
"ratingValue": r.ratingValue,
|
|
298
|
+
"bestRating": r.bestRating || 5
|
|
299
|
+
}
|
|
300
|
+
}));
|
|
301
|
+
return cleanSchema({
|
|
106
302
|
"@context": "https://schema.org",
|
|
107
303
|
"@type": "Product",
|
|
108
304
|
"name": data.name,
|
|
109
305
|
"description": data.description,
|
|
110
306
|
"image": data.image,
|
|
111
307
|
"sku": data.sku,
|
|
308
|
+
"gtin": data.gtin,
|
|
309
|
+
"mpn": data.mpn,
|
|
112
310
|
"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
|
-
},
|
|
311
|
+
"offers": offers,
|
|
120
312
|
"aggregateRating": data.rating ? {
|
|
121
313
|
"@type": "AggregateRating",
|
|
122
314
|
"ratingValue": data.rating,
|
|
123
315
|
"reviewCount": data.reviewCount || 1
|
|
124
|
-
} : void 0
|
|
125
|
-
|
|
316
|
+
} : void 0,
|
|
317
|
+
"review": reviewList && reviewList.length > 0 ? reviewList : void 0
|
|
318
|
+
});
|
|
126
319
|
}
|
|
127
320
|
function generateFAQSchema(questions) {
|
|
128
|
-
return {
|
|
321
|
+
return cleanSchema({
|
|
129
322
|
"@context": "https://schema.org",
|
|
130
323
|
"@type": "FAQPage",
|
|
131
324
|
"mainEntity": questions.map((item) => ({
|
|
@@ -136,10 +329,10 @@ function generateFAQSchema(questions) {
|
|
|
136
329
|
"text": item.a
|
|
137
330
|
}
|
|
138
331
|
}))
|
|
139
|
-
};
|
|
332
|
+
});
|
|
140
333
|
}
|
|
141
334
|
function generateBreadcrumbSchema(items) {
|
|
142
|
-
return {
|
|
335
|
+
return cleanSchema({
|
|
143
336
|
"@context": "https://schema.org",
|
|
144
337
|
"@type": "BreadcrumbList",
|
|
145
338
|
"itemListElement": items.map((item, index) => ({
|
|
@@ -148,10 +341,11 @@ function generateBreadcrumbSchema(items) {
|
|
|
148
341
|
"name": item.name,
|
|
149
342
|
"item": item.item
|
|
150
343
|
}))
|
|
151
|
-
};
|
|
344
|
+
});
|
|
152
345
|
}
|
|
153
346
|
function generateVideoSchema(data) {
|
|
154
|
-
|
|
347
|
+
validateSEO("VideoObject", data, ["name", "description", "thumbnailUrl", "uploadDate"]);
|
|
348
|
+
return cleanSchema({
|
|
155
349
|
"@context": "https://schema.org",
|
|
156
350
|
"@type": "VideoObject",
|
|
157
351
|
"name": data.name,
|
|
@@ -161,11 +355,11 @@ function generateVideoSchema(data) {
|
|
|
161
355
|
"duration": data.duration,
|
|
162
356
|
"contentUrl": data.contentUrl,
|
|
163
357
|
"embedUrl": data.embedUrl
|
|
164
|
-
};
|
|
358
|
+
});
|
|
165
359
|
}
|
|
166
360
|
function generateEventSchema(data) {
|
|
167
361
|
const isOnline = data.location && "url" in data.location;
|
|
168
|
-
return {
|
|
362
|
+
return cleanSchema({
|
|
169
363
|
"@context": "https://schema.org",
|
|
170
364
|
"@type": "Event",
|
|
171
365
|
"name": data.name,
|
|
@@ -188,10 +382,10 @@ function generateEventSchema(data) {
|
|
|
188
382
|
"priceCurrency": data.offers.currency,
|
|
189
383
|
"url": data.offers.url
|
|
190
384
|
} : void 0
|
|
191
|
-
};
|
|
385
|
+
});
|
|
192
386
|
}
|
|
193
387
|
function generateLocalBusinessSchema(data) {
|
|
194
|
-
return {
|
|
388
|
+
return cleanSchema({
|
|
195
389
|
"@context": "https://schema.org",
|
|
196
390
|
"@type": "LocalBusiness",
|
|
197
391
|
"name": data.name,
|
|
@@ -213,10 +407,10 @@ function generateLocalBusinessSchema(data) {
|
|
|
213
407
|
} : void 0,
|
|
214
408
|
"openingHours": data.openingHours,
|
|
215
409
|
"priceRange": data.priceRange
|
|
216
|
-
};
|
|
410
|
+
});
|
|
217
411
|
}
|
|
218
412
|
function generateSoftwareSchema(data) {
|
|
219
|
-
return {
|
|
413
|
+
return cleanSchema({
|
|
220
414
|
"@context": "https://schema.org",
|
|
221
415
|
"@type": "SoftwareApplication",
|
|
222
416
|
"name": data.name,
|
|
@@ -235,10 +429,10 @@ function generateSoftwareSchema(data) {
|
|
|
235
429
|
} : void 0,
|
|
236
430
|
"downloadUrl": data.downloadUrl,
|
|
237
431
|
"screenshot": data.screenshot
|
|
238
|
-
};
|
|
432
|
+
});
|
|
239
433
|
}
|
|
240
434
|
function generateBookSchema(data) {
|
|
241
|
-
return {
|
|
435
|
+
return cleanSchema({
|
|
242
436
|
"@context": "https://schema.org",
|
|
243
437
|
"@type": "Book",
|
|
244
438
|
"name": data.name,
|
|
@@ -261,10 +455,10 @@ function generateBookSchema(data) {
|
|
|
261
455
|
"image": data.image,
|
|
262
456
|
"inLanguage": data.inLanguage,
|
|
263
457
|
"genre": data.genre
|
|
264
|
-
};
|
|
458
|
+
});
|
|
265
459
|
}
|
|
266
460
|
function generateMovieSchema(data) {
|
|
267
|
-
return {
|
|
461
|
+
return cleanSchema({
|
|
268
462
|
"@context": "https://schema.org",
|
|
269
463
|
"@type": "Movie",
|
|
270
464
|
"name": data.name,
|
|
@@ -286,10 +480,10 @@ function generateMovieSchema(data) {
|
|
|
286
480
|
"ratingValue": data.rating,
|
|
287
481
|
"reviewCount": data.reviewCount || 1
|
|
288
482
|
} : void 0
|
|
289
|
-
};
|
|
483
|
+
});
|
|
290
484
|
}
|
|
291
485
|
function generatePodcastSchema(data) {
|
|
292
|
-
return {
|
|
486
|
+
return cleanSchema({
|
|
293
487
|
"@context": "https://schema.org",
|
|
294
488
|
"@type": "PodcastSeries",
|
|
295
489
|
"name": data.name,
|
|
@@ -302,10 +496,10 @@ function generatePodcastSchema(data) {
|
|
|
302
496
|
"webFeed": data.webFeed,
|
|
303
497
|
"url": data.url,
|
|
304
498
|
"genre": data.genre
|
|
305
|
-
};
|
|
499
|
+
});
|
|
306
500
|
}
|
|
307
501
|
function generatePodcastEpisodeSchema(data) {
|
|
308
|
-
return {
|
|
502
|
+
return cleanSchema({
|
|
309
503
|
"@context": "https://schema.org",
|
|
310
504
|
"@type": "PodcastEpisode",
|
|
311
505
|
"name": data.name,
|
|
@@ -322,7 +516,109 @@ function generatePodcastEpisodeSchema(data) {
|
|
|
322
516
|
"name": data.partOfSeries.name,
|
|
323
517
|
"url": data.partOfSeries.url
|
|
324
518
|
} : void 0
|
|
325
|
-
};
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
function generateHowToSchema(data) {
|
|
522
|
+
return cleanSchema({
|
|
523
|
+
"@context": "https://schema.org",
|
|
524
|
+
"@type": "HowTo",
|
|
525
|
+
"name": data.name,
|
|
526
|
+
"description": data.description,
|
|
527
|
+
"image": data.image,
|
|
528
|
+
"totalTime": data.totalTime,
|
|
529
|
+
"estimatedCost": data.estimatedCost ? {
|
|
530
|
+
"@type": "MonetaryAmount",
|
|
531
|
+
"currency": data.estimatedCost.currency,
|
|
532
|
+
"value": data.estimatedCost.value
|
|
533
|
+
} : void 0,
|
|
534
|
+
"supply": data.supply?.map((s) => ({ "@type": "HowToSupply", "name": s })),
|
|
535
|
+
"tool": data.tool?.map((t) => ({ "@type": "HowToTool", "name": t })),
|
|
536
|
+
"step": data.steps.map((step, index) => {
|
|
537
|
+
if (typeof step === "string") {
|
|
538
|
+
return { "@type": "HowToStep", "position": index + 1, "text": step };
|
|
539
|
+
}
|
|
540
|
+
return cleanSchema({
|
|
541
|
+
"@type": "HowToStep",
|
|
542
|
+
"position": index + 1,
|
|
543
|
+
"name": step.name,
|
|
544
|
+
"text": step.text,
|
|
545
|
+
"image": step.image,
|
|
546
|
+
"url": step.url
|
|
547
|
+
});
|
|
548
|
+
})
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
function generateRecipeSchema(data) {
|
|
552
|
+
return cleanSchema({
|
|
553
|
+
"@context": "https://schema.org",
|
|
554
|
+
"@type": "Recipe",
|
|
555
|
+
"name": data.name,
|
|
556
|
+
"description": data.description,
|
|
557
|
+
"image": data.image,
|
|
558
|
+
"author": { "@type": "Person", "name": data.author },
|
|
559
|
+
"datePublished": data.publishedDate,
|
|
560
|
+
"prepTime": data.prepTime,
|
|
561
|
+
"cookTime": data.cookTime,
|
|
562
|
+
"totalTime": data.totalTime,
|
|
563
|
+
"recipeYield": data.recipeYield,
|
|
564
|
+
"recipeCategory": data.recipeCategory,
|
|
565
|
+
"recipeCuisine": data.recipeCuisine,
|
|
566
|
+
"recipeIngredient": data.ingredients,
|
|
567
|
+
"recipeInstructions": data.instructions.map((step) => cleanSchema({
|
|
568
|
+
"@type": "HowToStep",
|
|
569
|
+
"name": step.name,
|
|
570
|
+
"text": step.text,
|
|
571
|
+
"image": step.image
|
|
572
|
+
})),
|
|
573
|
+
"aggregateRating": data.rating ? {
|
|
574
|
+
"@type": "AggregateRating",
|
|
575
|
+
"ratingValue": data.rating,
|
|
576
|
+
"reviewCount": data.reviewCount || 1
|
|
577
|
+
} : void 0
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
function generateJobPostingSchema(data) {
|
|
581
|
+
return cleanSchema({
|
|
582
|
+
"@context": "https://schema.org",
|
|
583
|
+
"@type": "JobPosting",
|
|
584
|
+
"title": data.title,
|
|
585
|
+
"description": data.description,
|
|
586
|
+
"datePosted": data.datePosted,
|
|
587
|
+
"validThrough": data.validThrough,
|
|
588
|
+
"employmentType": data.employmentType,
|
|
589
|
+
"jobLocationType": data.remote ? "TELECOMMUTE" : void 0,
|
|
590
|
+
"hiringOrganization": {
|
|
591
|
+
"@type": "Organization",
|
|
592
|
+
"name": data.hiringOrganization.name,
|
|
593
|
+
"sameAs": data.hiringOrganization.sameAs,
|
|
594
|
+
"logo": data.hiringOrganization.logo
|
|
595
|
+
},
|
|
596
|
+
"jobLocation": {
|
|
597
|
+
"@type": "Place",
|
|
598
|
+
"address": {
|
|
599
|
+
"@type": "PostalAddress",
|
|
600
|
+
"streetAddress": data.jobLocation.streetAddress,
|
|
601
|
+
"addressLocality": data.jobLocation.addressLocality,
|
|
602
|
+
"addressRegion": data.jobLocation.addressRegion,
|
|
603
|
+
"postalCode": data.jobLocation.postalCode,
|
|
604
|
+
"addressCountry": data.jobLocation.addressCountry
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
"baseSalary": data.baseSalary ? {
|
|
608
|
+
"@type": "MonetaryAmount",
|
|
609
|
+
"currency": data.baseSalary.currency,
|
|
610
|
+
"value": typeof data.baseSalary.value === "number" ? {
|
|
611
|
+
"@type": "QuantitativeValue",
|
|
612
|
+
"value": data.baseSalary.value,
|
|
613
|
+
"unitText": data.baseSalary.unitText || "MONTH"
|
|
614
|
+
} : {
|
|
615
|
+
"@type": "QuantitativeValue",
|
|
616
|
+
"minValue": data.baseSalary.value.minValue,
|
|
617
|
+
"maxValue": data.baseSalary.value.maxValue,
|
|
618
|
+
"unitText": data.baseSalary.unitText || "MONTH"
|
|
619
|
+
}
|
|
620
|
+
} : void 0
|
|
621
|
+
});
|
|
326
622
|
}
|
|
327
623
|
|
|
328
624
|
// src/core/metadata.ts
|
|
@@ -366,6 +662,9 @@ function toNextMetadata(props, config) {
|
|
|
366
662
|
},
|
|
367
663
|
other: {}
|
|
368
664
|
};
|
|
665
|
+
if (config.facebookAppId) {
|
|
666
|
+
metadata.other["fb:app_id"] = config.facebookAppId;
|
|
667
|
+
}
|
|
369
668
|
if (props.alternates && props.alternates.length > 0) {
|
|
370
669
|
const languages = {};
|
|
371
670
|
props.alternates.forEach((alt) => {
|
|
@@ -373,6 +672,12 @@ function toNextMetadata(props, config) {
|
|
|
373
672
|
});
|
|
374
673
|
metadata.alternates.languages = languages;
|
|
375
674
|
}
|
|
675
|
+
if (props.prev) {
|
|
676
|
+
metadata.alternates.prev = props.prev;
|
|
677
|
+
}
|
|
678
|
+
if (props.next) {
|
|
679
|
+
metadata.alternates.next = props.next;
|
|
680
|
+
}
|
|
376
681
|
metadata.appleWebApp = {
|
|
377
682
|
capable: true,
|
|
378
683
|
title: config.name,
|
|
@@ -380,6 +685,45 @@ function toNextMetadata(props, config) {
|
|
|
380
685
|
};
|
|
381
686
|
if (config.themeColor) metadata.themeColor = config.themeColor;
|
|
382
687
|
if (config.manifest) metadata.manifest = config.manifest;
|
|
688
|
+
if (props.type === "article") {
|
|
689
|
+
if (props.publishedTime) {
|
|
690
|
+
metadata.openGraph.publishedTime = props.publishedTime;
|
|
691
|
+
}
|
|
692
|
+
if (props.modifiedTime) {
|
|
693
|
+
metadata.openGraph.modifiedTime = props.modifiedTime;
|
|
694
|
+
}
|
|
695
|
+
if (props.author) {
|
|
696
|
+
metadata.openGraph.authors = [props.author.name];
|
|
697
|
+
}
|
|
698
|
+
if (props.section) {
|
|
699
|
+
metadata.openGraph.section = props.section;
|
|
700
|
+
}
|
|
701
|
+
if (props.tags?.length) {
|
|
702
|
+
metadata.openGraph.tags = props.tags;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
if (props.type === "product" && props.product) {
|
|
706
|
+
if (props.product.price !== void 0 && props.product.currency) {
|
|
707
|
+
metadata.other["product:price:amount"] = props.product.price.toString();
|
|
708
|
+
metadata.other["product:price:currency"] = props.product.currency;
|
|
709
|
+
}
|
|
710
|
+
if (props.product.availability) {
|
|
711
|
+
metadata.other["product:availability"] = props.product.availability;
|
|
712
|
+
}
|
|
713
|
+
if (props.product.brand) {
|
|
714
|
+
metadata.other["product:brand"] = props.product.brand;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
if (props.readingTime) {
|
|
718
|
+
metadata.other["twitter:label1"] = "Reading time";
|
|
719
|
+
metadata.other["twitter:data1"] = `${props.readingTime} min`;
|
|
720
|
+
}
|
|
721
|
+
if (props.whatsappImage) {
|
|
722
|
+
metadata.other["og:image:secure_url"] = props.whatsappImage;
|
|
723
|
+
}
|
|
724
|
+
if (Object.keys(metadata.other).length === 0) {
|
|
725
|
+
delete metadata.other;
|
|
726
|
+
}
|
|
383
727
|
return metadata;
|
|
384
728
|
}
|
|
385
729
|
function generatePaginationLinks(baseUrl, currentPage, totalPages) {
|
|
@@ -392,17 +736,304 @@ function generatePaginationLinks(baseUrl, currentPage, totalPages) {
|
|
|
392
736
|
canonical: currentPage === 1 ? cleanBase : `${cleanBase}?page=${currentPage}`
|
|
393
737
|
};
|
|
394
738
|
}
|
|
395
|
-
function generatePaginatedTitle(title, page, suffix = "
|
|
739
|
+
function generatePaginatedTitle(title, page, suffix = "Page") {
|
|
396
740
|
return page > 1 ? `${title} - ${suffix} ${page}` : title;
|
|
397
741
|
}
|
|
398
742
|
|
|
743
|
+
// src/core/JsonLd.tsx
|
|
744
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
745
|
+
function JsonLd({ schema, graph = false }) {
|
|
746
|
+
const schemas = Array.isArray(schema) ? schema : [schema];
|
|
747
|
+
if (graph && schemas.length > 1) {
|
|
748
|
+
const graphData = {
|
|
749
|
+
"@context": "https://schema.org",
|
|
750
|
+
"@graph": schemas.map((s) => {
|
|
751
|
+
const { "@context": _, ...rest } = s;
|
|
752
|
+
return rest;
|
|
753
|
+
})
|
|
754
|
+
};
|
|
755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
756
|
+
"script",
|
|
757
|
+
{
|
|
758
|
+
type: "application/ld+json",
|
|
759
|
+
dangerouslySetInnerHTML: { __html: JSON.stringify(graphData) }
|
|
760
|
+
}
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: schemas.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
764
|
+
"script",
|
|
765
|
+
{
|
|
766
|
+
type: "application/ld+json",
|
|
767
|
+
dangerouslySetInnerHTML: { __html: JSON.stringify(s) }
|
|
768
|
+
},
|
|
769
|
+
i
|
|
770
|
+
)) });
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
// src/core/product-metadata.ts
|
|
774
|
+
function generateProductMetadata(product, config) {
|
|
775
|
+
const primaryImage = Array.isArray(product.image) ? product.image[0] : product.image;
|
|
776
|
+
const seoData = {
|
|
777
|
+
title: product.metaTitle || product.name,
|
|
778
|
+
description: product.metaDescription || product.description,
|
|
779
|
+
image: product.ogImage || primaryImage,
|
|
780
|
+
canonical: product.canonical || product.url,
|
|
781
|
+
type: "product",
|
|
782
|
+
noindex: product.noindex,
|
|
783
|
+
ogTitle: product.name,
|
|
784
|
+
ogDescription: product.description,
|
|
785
|
+
ogImage: product.ogImage || primaryImage,
|
|
786
|
+
ogImageWidth: product.ogImageWidth || 1200,
|
|
787
|
+
ogImageHeight: product.ogImageHeight || 630,
|
|
788
|
+
ogType: "product",
|
|
789
|
+
product: {
|
|
790
|
+
sku: product.sku,
|
|
791
|
+
brand: product.brand,
|
|
792
|
+
price: product.price,
|
|
793
|
+
currency: product.currency,
|
|
794
|
+
availability: product.availability,
|
|
795
|
+
rating: product.rating,
|
|
796
|
+
reviewCount: product.reviewCount
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
const metadata = toNextMetadata(seoData, config);
|
|
800
|
+
if (product.price !== void 0 && product.currency) {
|
|
801
|
+
metadata.other = {
|
|
802
|
+
...metadata.other,
|
|
803
|
+
"product:price:amount": product.price.toString(),
|
|
804
|
+
"product:price:currency": product.currency
|
|
805
|
+
};
|
|
806
|
+
if (product.availability) {
|
|
807
|
+
metadata.other["product:availability"] = product.availability;
|
|
808
|
+
}
|
|
809
|
+
if (product.brand) {
|
|
810
|
+
metadata.other["product:brand"] = product.brand;
|
|
811
|
+
}
|
|
812
|
+
if (product.condition) {
|
|
813
|
+
metadata.other["product:condition"] = product.condition;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
const productSchema = generateProductSchema({
|
|
817
|
+
name: product.name,
|
|
818
|
+
description: product.description,
|
|
819
|
+
image: product.image,
|
|
820
|
+
sku: product.sku,
|
|
821
|
+
gtin: product.gtin,
|
|
822
|
+
mpn: product.mpn,
|
|
823
|
+
brand: product.brand,
|
|
824
|
+
price: product.price,
|
|
825
|
+
currency: product.currency,
|
|
826
|
+
availability: product.availability,
|
|
827
|
+
rating: product.rating,
|
|
828
|
+
reviewCount: product.reviewCount,
|
|
829
|
+
url: product.url,
|
|
830
|
+
condition: product.condition,
|
|
831
|
+
reviews: product.reviews,
|
|
832
|
+
returnPolicy: product.returnPolicy,
|
|
833
|
+
shipping: product.shipping,
|
|
834
|
+
variants: product.variants,
|
|
835
|
+
seller: product.seller
|
|
836
|
+
});
|
|
837
|
+
const breadcrumbItems = product.breadcrumbs || [
|
|
838
|
+
{ name: "Home", item: config.url },
|
|
839
|
+
{ name: "Shop", item: `${config.url}/shop` },
|
|
840
|
+
...product.category ? [{ name: product.category, item: `${config.url}/categories/${encodeURIComponent(product.category)}` }] : [],
|
|
841
|
+
{ name: product.name, item: product.url }
|
|
842
|
+
];
|
|
843
|
+
const breadcrumbSchema = generateBreadcrumbSchema(breadcrumbItems);
|
|
844
|
+
const organizationSchema = generateOrganizationSchema(config);
|
|
845
|
+
const websiteSchema = generateWebSiteSchema(config);
|
|
846
|
+
return {
|
|
847
|
+
metadata,
|
|
848
|
+
schemas: [productSchema, breadcrumbSchema, organizationSchema, websiteSchema],
|
|
849
|
+
productSchema,
|
|
850
|
+
breadcrumbSchema,
|
|
851
|
+
organizationSchema,
|
|
852
|
+
websiteSchema
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
// src/core/article-metadata.ts
|
|
857
|
+
function generateArticleMetadata(article, config) {
|
|
858
|
+
const primaryImage = Array.isArray(article.image) ? article.image[0] : article.image;
|
|
859
|
+
const seoData = {
|
|
860
|
+
title: article.metaTitle || article.title,
|
|
861
|
+
description: article.metaDescription || article.description,
|
|
862
|
+
image: article.ogImage || primaryImage,
|
|
863
|
+
canonical: article.canonical || article.url,
|
|
864
|
+
type: "article",
|
|
865
|
+
noindex: article.noindex,
|
|
866
|
+
publishedTime: article.publishedTime,
|
|
867
|
+
modifiedTime: article.modifiedTime,
|
|
868
|
+
author: article.author,
|
|
869
|
+
section: article.category,
|
|
870
|
+
tags: article.tags,
|
|
871
|
+
readingTime: article.readingTime,
|
|
872
|
+
ogTitle: article.title,
|
|
873
|
+
ogDescription: article.description,
|
|
874
|
+
ogImage: article.ogImage || primaryImage,
|
|
875
|
+
ogImageWidth: article.ogImageWidth || 1200,
|
|
876
|
+
ogImageHeight: article.ogImageHeight || 630,
|
|
877
|
+
ogType: "article"
|
|
878
|
+
};
|
|
879
|
+
const metadata = toNextMetadata(seoData, config);
|
|
880
|
+
if (article.publishedTime) {
|
|
881
|
+
metadata.other = {
|
|
882
|
+
...metadata.other,
|
|
883
|
+
"article:published_time": article.publishedTime
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
if (article.modifiedTime) {
|
|
887
|
+
metadata.other = {
|
|
888
|
+
...metadata.other,
|
|
889
|
+
"article:modified_time": article.modifiedTime
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
if (article.category) {
|
|
893
|
+
metadata.other = {
|
|
894
|
+
...metadata.other,
|
|
895
|
+
"article:section": article.category
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
if (article.tags?.length) {
|
|
899
|
+
metadata.other = {
|
|
900
|
+
...metadata.other,
|
|
901
|
+
"article:tag": article.tags.join(",")
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
const articleSchema = generateArticleSchema({
|
|
905
|
+
title: article.title,
|
|
906
|
+
description: article.description,
|
|
907
|
+
image: article.image,
|
|
908
|
+
publishedTime: article.publishedTime,
|
|
909
|
+
modifiedTime: article.modifiedTime,
|
|
910
|
+
author: article.author,
|
|
911
|
+
url: article.url,
|
|
912
|
+
wordCount: article.wordCount
|
|
913
|
+
}, config);
|
|
914
|
+
const breadcrumbItems = article.breadcrumbs || [
|
|
915
|
+
{ name: "Home", item: config.url },
|
|
916
|
+
...article.category ? [{ name: article.category, item: `${config.url}/category/${encodeURIComponent(article.category)}` }] : [],
|
|
917
|
+
{ name: article.title, item: article.url }
|
|
918
|
+
];
|
|
919
|
+
const breadcrumbSchema = generateBreadcrumbSchema(breadcrumbItems);
|
|
920
|
+
const organizationSchema = generateOrganizationSchema(config);
|
|
921
|
+
const websiteSchema = generateWebSiteSchema(config);
|
|
922
|
+
return {
|
|
923
|
+
metadata,
|
|
924
|
+
schemas: [articleSchema, breadcrumbSchema, organizationSchema, websiteSchema],
|
|
925
|
+
articleSchema,
|
|
926
|
+
breadcrumbSchema,
|
|
927
|
+
organizationSchema,
|
|
928
|
+
websiteSchema
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// src/core/category-metadata.ts
|
|
933
|
+
function generateCategoryMetadata(category, config) {
|
|
934
|
+
const page = category.page || 1;
|
|
935
|
+
const totalPages = category.totalPages || 1;
|
|
936
|
+
const pageSuffix = category.pageSuffix || "Page";
|
|
937
|
+
const pagination = generatePaginationLinks(category.url, page, totalPages);
|
|
938
|
+
const title = generatePaginatedTitle(
|
|
939
|
+
category.metaTitle || category.name,
|
|
940
|
+
page,
|
|
941
|
+
pageSuffix
|
|
942
|
+
);
|
|
943
|
+
const seoData = {
|
|
944
|
+
title,
|
|
945
|
+
description: category.metaDescription || category.description,
|
|
946
|
+
image: category.image,
|
|
947
|
+
canonical: pagination.canonical,
|
|
948
|
+
type: "website",
|
|
949
|
+
noindex: category.noindex,
|
|
950
|
+
prev: pagination.prev,
|
|
951
|
+
next: pagination.next
|
|
952
|
+
};
|
|
953
|
+
const metadata = toNextMetadata(seoData, config);
|
|
954
|
+
const collectionPageSchema = generateCollectionPageSchema({
|
|
955
|
+
name: category.name,
|
|
956
|
+
description: category.description,
|
|
957
|
+
url: pagination.canonical || category.url,
|
|
958
|
+
image: category.image,
|
|
959
|
+
numberOfItems: category.items?.length
|
|
960
|
+
}, config);
|
|
961
|
+
const breadcrumbItems = category.breadcrumbs || [
|
|
962
|
+
{ name: "Home", item: config.url },
|
|
963
|
+
...category.parentCategory ? [{ name: category.parentCategory, item: `${config.url}/categories` }] : [],
|
|
964
|
+
{ name: category.name, item: category.url }
|
|
965
|
+
];
|
|
966
|
+
const breadcrumbSchema = generateBreadcrumbSchema(breadcrumbItems);
|
|
967
|
+
const organizationSchema = generateOrganizationSchema(config);
|
|
968
|
+
let itemListSchema;
|
|
969
|
+
if (category.items && category.items.length > 0) {
|
|
970
|
+
itemListSchema = generateItemListSchema({
|
|
971
|
+
name: category.name,
|
|
972
|
+
url: pagination.canonical || category.url,
|
|
973
|
+
items: category.items
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
const schemas = [collectionPageSchema, breadcrumbSchema, organizationSchema];
|
|
977
|
+
if (itemListSchema) schemas.push(itemListSchema);
|
|
978
|
+
return {
|
|
979
|
+
metadata,
|
|
980
|
+
schemas,
|
|
981
|
+
collectionPageSchema,
|
|
982
|
+
breadcrumbSchema,
|
|
983
|
+
organizationSchema,
|
|
984
|
+
itemListSchema
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// src/core/homepage-metadata.ts
|
|
989
|
+
function generateHomepageMetadata(input, config) {
|
|
990
|
+
const seoData = {
|
|
991
|
+
title: input.title || config.name,
|
|
992
|
+
description: input.description || config.description,
|
|
993
|
+
image: input.ogImage || input.image || config.logo,
|
|
994
|
+
canonical: input.canonical || config.url,
|
|
995
|
+
type: "website",
|
|
996
|
+
ogTitle: input.title || config.name,
|
|
997
|
+
ogDescription: input.description || config.description,
|
|
998
|
+
ogImage: input.ogImage || input.image || config.logo,
|
|
999
|
+
ogImageWidth: input.ogImageWidth || 1200,
|
|
1000
|
+
ogImageHeight: input.ogImageHeight || 630
|
|
1001
|
+
};
|
|
1002
|
+
const metadata = toNextMetadata(seoData, config);
|
|
1003
|
+
const webPageSchema = generateWebPageSchema({
|
|
1004
|
+
name: input.title || config.name,
|
|
1005
|
+
description: input.description || config.description,
|
|
1006
|
+
url: config.url,
|
|
1007
|
+
image: input.image || config.logo
|
|
1008
|
+
}, config);
|
|
1009
|
+
const organizationSchema = generateOrganizationSchema({
|
|
1010
|
+
...config,
|
|
1011
|
+
socialLinks: input.socialLinks || config.socialLinks
|
|
1012
|
+
});
|
|
1013
|
+
const websiteSchema = generateWebSiteSchema(config);
|
|
1014
|
+
const schemas = [webPageSchema, organizationSchema, websiteSchema];
|
|
1015
|
+
let localBusinessSchema;
|
|
1016
|
+
if (input.localBusiness) {
|
|
1017
|
+
localBusinessSchema = generateLocalBusinessSchema(input.localBusiness);
|
|
1018
|
+
schemas.push(localBusinessSchema);
|
|
1019
|
+
}
|
|
1020
|
+
return {
|
|
1021
|
+
metadata,
|
|
1022
|
+
schemas,
|
|
1023
|
+
webPageSchema,
|
|
1024
|
+
organizationSchema,
|
|
1025
|
+
websiteSchema,
|
|
1026
|
+
localBusinessSchema
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
|
|
399
1030
|
// src/components/SEOProvider.tsx
|
|
400
1031
|
var import_react = require("react");
|
|
401
1032
|
var import_react_helmet_async = require("react-helmet-async");
|
|
402
|
-
var
|
|
1033
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
403
1034
|
var SEOContext = (0, import_react.createContext)(void 0);
|
|
404
1035
|
var SEOProvider = ({ config, children, helmetContext }) => {
|
|
405
|
-
return /* @__PURE__ */ (0,
|
|
1036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SEOContext.Provider, { value: { config }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_helmet_async.HelmetProvider, { context: helmetContext, children }) });
|
|
406
1037
|
};
|
|
407
1038
|
var useSEOConfig = () => {
|
|
408
1039
|
const context = (0, import_react.useContext)(SEOContext);
|
|
@@ -414,7 +1045,7 @@ var useSEOConfig = () => {
|
|
|
414
1045
|
|
|
415
1046
|
// src/components/SEO.tsx
|
|
416
1047
|
var import_react_helmet_async2 = require("react-helmet-async");
|
|
417
|
-
var
|
|
1048
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
418
1049
|
var SEO = (props) => {
|
|
419
1050
|
const config = useSEOConfig();
|
|
420
1051
|
const title = props.title ? `${props.title} | ${config.name}` : config.name;
|
|
@@ -493,57 +1124,57 @@ var SEO = (props) => {
|
|
|
493
1124
|
schemas.push(props.schema);
|
|
494
1125
|
}
|
|
495
1126
|
}
|
|
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,
|
|
1127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_helmet_async2.Helmet, { children: [
|
|
1128
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("title", { children: title }),
|
|
1129
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "description", content: description }),
|
|
1130
|
+
props.keywords && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "keywords", content: props.keywords.join(", ") }),
|
|
1131
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "robots", content: props.noindex ? "noindex, nofollow" : props.robots || "index, follow" }),
|
|
1132
|
+
!props.noindex && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "canonical", href: url }),
|
|
1133
|
+
props.prev && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "prev", href: props.prev }),
|
|
1134
|
+
props.next && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "next", href: props.next }),
|
|
1135
|
+
config.language && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { httpEquiv: "content-language", content: config.language }),
|
|
1136
|
+
props.alternates?.map((alt, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "alternate", hrefLang: alt.hreflang, href: alt.href }, i)),
|
|
1137
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:type", content: props.ogType || (props.type === "article" ? "article" : "website") }),
|
|
1138
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:title", content: props.ogTitle || title }),
|
|
1139
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:description", content: props.ogDescription || description }),
|
|
1140
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:image", content: props.ogImage || image }),
|
|
1141
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:url", content: url }),
|
|
1142
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:site_name", content: config.name }),
|
|
1143
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:locale", content: props.ogLocale || config.language || "en_US" }),
|
|
1144
|
+
config.facebookAppId && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "fb:app_id", content: config.facebookAppId }),
|
|
1145
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:card", content: props.twitterCard || "summary_large_image" }),
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:title", content: props.twitterTitle || title }),
|
|
1147
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:description", content: props.twitterDescription || description }),
|
|
1148
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:image", content: props.twitterImage || image }),
|
|
1149
|
+
config.twitterHandle && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:site", content: config.twitterHandle }),
|
|
1150
|
+
config.twitterHandle && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:creator", content: config.twitterHandle }),
|
|
1151
|
+
props.readingTime && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:label1", content: "Reading time" }),
|
|
1152
|
+
props.readingTime && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "twitter:data1", content: `${props.readingTime} min` }),
|
|
1153
|
+
props.type === "article" && props.publishedTime && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "article:published_time", content: props.publishedTime }),
|
|
1154
|
+
props.type === "article" && props.modifiedTime && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "article:modified_time", content: props.modifiedTime }),
|
|
1155
|
+
props.type === "article" && props.section && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "article:section", content: props.section }),
|
|
1156
|
+
props.type === "article" && props.tags?.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "article:tag", content: tag }, tag)),
|
|
1157
|
+
config.themeColor && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "theme-color", content: config.themeColor }),
|
|
1158
|
+
config.manifest && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "manifest", href: config.manifest }),
|
|
1159
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "apple-mobile-web-app-capable", content: "yes" }),
|
|
1160
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "apple-mobile-web-app-status-bar-style", content: "default" }),
|
|
1161
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { name: "apple-mobile-web-app-title", content: config.name }),
|
|
1162
|
+
props.dnsPrefetch?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "dns-prefetch", href: d }, d)),
|
|
1163
|
+
props.preconnect?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "preconnect", href: d }, d)),
|
|
1164
|
+
props.prefetch?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "prefetch", href: d }, d)),
|
|
1165
|
+
props.preload?.map((p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("link", { rel: "preload", href: p.href, as: p.as, type: p.type }, p.href)),
|
|
1166
|
+
(props.whatsappImage || image) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "og:image:secure_url", content: props.whatsappImage || image }),
|
|
1167
|
+
props.whatsappDescription && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meta", { property: "whatsapp:description", content: props.whatsappDescription }),
|
|
1168
|
+
config.googleAnalyticsId && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("script", { async: true, src: `https://www.googletagmanager.com/gtag/js?id=${config.googleAnalyticsId}` }),
|
|
1169
|
+
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}');` }),
|
|
1170
|
+
schemas.map((schema, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }, index)),
|
|
540
1171
|
props.children
|
|
541
1172
|
] });
|
|
542
1173
|
};
|
|
543
1174
|
|
|
544
1175
|
// src/components/Breadcrumb.tsx
|
|
545
1176
|
var import_react_helmet_async3 = require("react-helmet-async");
|
|
546
|
-
var
|
|
1177
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
547
1178
|
var Breadcrumb = ({
|
|
548
1179
|
items,
|
|
549
1180
|
className = "breadcrumb",
|
|
@@ -560,22 +1191,22 @@ var Breadcrumb = ({
|
|
|
560
1191
|
"item": item.item
|
|
561
1192
|
}))
|
|
562
1193
|
};
|
|
563
|
-
return /* @__PURE__ */ (0,
|
|
564
|
-
/* @__PURE__ */ (0,
|
|
565
|
-
/* @__PURE__ */ (0,
|
|
1194
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1195
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_helmet_async3.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) }),
|
|
1196
|
+
/* @__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
1197
|
const isLast = index === items.length - 1;
|
|
567
|
-
return /* @__PURE__ */ (0,
|
|
568
|
-
renderLink ? renderLink(item, isLast) : isLast ? /* @__PURE__ */ (0,
|
|
569
|
-
!isLast && /* @__PURE__ */ (0,
|
|
1198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { style: { display: "flex", alignItems: "center" }, children: [
|
|
1199
|
+
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 }),
|
|
1200
|
+
!isLast && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { margin: "0 8px" }, children: separator })
|
|
570
1201
|
] }, index);
|
|
571
1202
|
}) }) })
|
|
572
1203
|
] });
|
|
573
1204
|
};
|
|
574
1205
|
|
|
575
1206
|
// src/components/SeoArticle.tsx
|
|
576
|
-
var
|
|
1207
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
577
1208
|
var SeoArticle = ({ article, ...rest }) => {
|
|
578
|
-
return /* @__PURE__ */ (0,
|
|
1209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
579
1210
|
SEO,
|
|
580
1211
|
{
|
|
581
1212
|
type: "article",
|
|
@@ -593,9 +1224,9 @@ var SeoArticle = ({ article, ...rest }) => {
|
|
|
593
1224
|
};
|
|
594
1225
|
|
|
595
1226
|
// src/components/SeoProduct.tsx
|
|
596
|
-
var
|
|
1227
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
597
1228
|
var SeoProduct = ({ item, ...rest }) => {
|
|
598
|
-
return /* @__PURE__ */ (0,
|
|
1229
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
599
1230
|
SEO,
|
|
600
1231
|
{
|
|
601
1232
|
type: "product",
|
|
@@ -618,7 +1249,7 @@ var SeoProduct = ({ item, ...rest }) => {
|
|
|
618
1249
|
|
|
619
1250
|
// src/components/SeoFAQ.tsx
|
|
620
1251
|
var import_react_helmet_async4 = require("react-helmet-async");
|
|
621
|
-
var
|
|
1252
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
622
1253
|
var SeoFAQ = ({ items }) => {
|
|
623
1254
|
const schema = {
|
|
624
1255
|
"@context": "https://schema.org",
|
|
@@ -632,12 +1263,12 @@ var SeoFAQ = ({ items }) => {
|
|
|
632
1263
|
}
|
|
633
1264
|
}))
|
|
634
1265
|
};
|
|
635
|
-
return /* @__PURE__ */ (0,
|
|
1266
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_helmet_async4.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
636
1267
|
};
|
|
637
1268
|
|
|
638
1269
|
// src/components/SeoVideo.tsx
|
|
639
1270
|
var import_react_helmet_async5 = require("react-helmet-async");
|
|
640
|
-
var
|
|
1271
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
641
1272
|
var SeoVideo = ({ video }) => {
|
|
642
1273
|
const schema = {
|
|
643
1274
|
"@context": "https://schema.org",
|
|
@@ -655,12 +1286,12 @@ var SeoVideo = ({ video }) => {
|
|
|
655
1286
|
"userInteractionCount": video.interactionStatistic.viewCount
|
|
656
1287
|
} : void 0
|
|
657
1288
|
};
|
|
658
|
-
return /* @__PURE__ */ (0,
|
|
1289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_helmet_async5.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
659
1290
|
};
|
|
660
1291
|
|
|
661
1292
|
// src/components/SeoEvent.tsx
|
|
662
1293
|
var import_react_helmet_async6 = require("react-helmet-async");
|
|
663
|
-
var
|
|
1294
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
664
1295
|
var SeoEvent = ({ event }) => {
|
|
665
1296
|
const schema = {
|
|
666
1297
|
"@context": "https://schema.org",
|
|
@@ -696,12 +1327,12 @@ var SeoEvent = ({ event }) => {
|
|
|
696
1327
|
"url": event.organizer.url
|
|
697
1328
|
} : void 0
|
|
698
1329
|
};
|
|
699
|
-
return /* @__PURE__ */ (0,
|
|
1330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_helmet_async6.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
700
1331
|
};
|
|
701
1332
|
|
|
702
1333
|
// src/components/SeoLocalBusiness.tsx
|
|
703
1334
|
var import_react_helmet_async7 = require("react-helmet-async");
|
|
704
|
-
var
|
|
1335
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
705
1336
|
var SeoLocalBusiness = ({ business }) => {
|
|
706
1337
|
const schema = {
|
|
707
1338
|
"@context": "https://schema.org",
|
|
@@ -728,23 +1359,29 @@ var SeoLocalBusiness = ({ business }) => {
|
|
|
728
1359
|
} : void 0,
|
|
729
1360
|
"openingHours": business.openingHours
|
|
730
1361
|
};
|
|
731
|
-
return /* @__PURE__ */ (0,
|
|
1362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_helmet_async7.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
732
1363
|
};
|
|
733
1364
|
|
|
734
1365
|
// src/components/SeoCategory.tsx
|
|
735
|
-
var
|
|
736
|
-
var SeoCategory = ({
|
|
1366
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1367
|
+
var SeoCategory = ({
|
|
1368
|
+
category,
|
|
1369
|
+
page = 1,
|
|
1370
|
+
totalPage = 1,
|
|
1371
|
+
pageSuffix = "Page",
|
|
1372
|
+
...rest
|
|
1373
|
+
}) => {
|
|
737
1374
|
const hasNext = page < totalPage;
|
|
738
1375
|
const hasPrev = page > 1;
|
|
739
1376
|
const baseUrl = category.url.split("?")[0];
|
|
740
1377
|
const nextUrl = hasNext ? `${baseUrl}?page=${page + 1}` : void 0;
|
|
741
1378
|
const prevUrl = hasPrev ? page === 2 ? baseUrl : `${baseUrl}?page=${page - 1}` : void 0;
|
|
742
1379
|
const canonical = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
|
|
743
|
-
return /* @__PURE__ */ (0,
|
|
1380
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
744
1381
|
SEO,
|
|
745
1382
|
{
|
|
746
1383
|
type: "website",
|
|
747
|
-
title: `${category.name}${page > 1 ? ` -
|
|
1384
|
+
title: `${category.name}${page > 1 ? ` - ${pageSuffix} ${page}` : ""}`,
|
|
748
1385
|
description: category.description,
|
|
749
1386
|
image: category.image,
|
|
750
1387
|
canonical,
|
|
@@ -763,20 +1400,29 @@ var SeoCategory = ({ category, page = 1, totalPage = 1, ...rest }) => {
|
|
|
763
1400
|
};
|
|
764
1401
|
|
|
765
1402
|
// src/components/SeoTag.tsx
|
|
766
|
-
var
|
|
767
|
-
var SeoTag = ({
|
|
1403
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1404
|
+
var SeoTag = ({
|
|
1405
|
+
tag,
|
|
1406
|
+
page = 1,
|
|
1407
|
+
totalPage = 1,
|
|
1408
|
+
titlePrefix = "Tag",
|
|
1409
|
+
pageSuffix = "Page",
|
|
1410
|
+
defaultDescription,
|
|
1411
|
+
...rest
|
|
1412
|
+
}) => {
|
|
768
1413
|
const hasNext = page < totalPage;
|
|
769
1414
|
const hasPrev = page > 1;
|
|
770
1415
|
const baseUrl = tag.url.split("?")[0];
|
|
771
1416
|
const nextUrl = hasNext ? `${baseUrl}?page=${page + 1}` : void 0;
|
|
772
1417
|
const prevUrl = hasPrev ? page === 2 ? baseUrl : `${baseUrl}?page=${page - 1}` : void 0;
|
|
773
1418
|
const canonical = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
|
|
774
|
-
|
|
1419
|
+
const desc = tag.description || (defaultDescription ? defaultDescription.replace("{name}", tag.name) : `All posts tagged with ${tag.name}`);
|
|
1420
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
775
1421
|
SEO,
|
|
776
1422
|
{
|
|
777
1423
|
type: "website",
|
|
778
|
-
title:
|
|
779
|
-
description:
|
|
1424
|
+
title: `${titlePrefix}: ${tag.name}${page > 1 ? ` - ${pageSuffix} ${page}` : ""}`,
|
|
1425
|
+
description: desc,
|
|
780
1426
|
canonical,
|
|
781
1427
|
next: nextUrl,
|
|
782
1428
|
prev: prevUrl,
|
|
@@ -786,19 +1432,25 @@ var SeoTag = ({ tag, page = 1, totalPage = 1, ...rest }) => {
|
|
|
786
1432
|
};
|
|
787
1433
|
|
|
788
1434
|
// src/components/SeoAuthor.tsx
|
|
789
|
-
var
|
|
790
|
-
var SeoAuthor = ({
|
|
1435
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1436
|
+
var SeoAuthor = ({
|
|
1437
|
+
author,
|
|
1438
|
+
page = 1,
|
|
1439
|
+
totalPage = 1,
|
|
1440
|
+
pageSuffix = "Page",
|
|
1441
|
+
...rest
|
|
1442
|
+
}) => {
|
|
791
1443
|
const hasNext = page < totalPage;
|
|
792
1444
|
const hasPrev = page > 1;
|
|
793
1445
|
const baseUrl = author.url.split("?")[0];
|
|
794
1446
|
const nextUrl = hasNext ? `${baseUrl}?page=${page + 1}` : void 0;
|
|
795
1447
|
const prevUrl = hasPrev ? page === 2 ? baseUrl : `${baseUrl}?page=${page - 1}` : void 0;
|
|
796
1448
|
const canonical = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
|
|
797
|
-
return /* @__PURE__ */ (0,
|
|
1449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
798
1450
|
SEO,
|
|
799
1451
|
{
|
|
800
1452
|
type: "profile",
|
|
801
|
-
title: `${author.name}${page > 1 ? ` -
|
|
1453
|
+
title: `${author.name}${page > 1 ? ` - ${pageSuffix} ${page}` : ""}`,
|
|
802
1454
|
description: author.description,
|
|
803
1455
|
image: author.image,
|
|
804
1456
|
canonical,
|
|
@@ -820,7 +1472,7 @@ var SeoAuthor = ({ author, page = 1, totalPage = 1, ...rest }) => {
|
|
|
820
1472
|
|
|
821
1473
|
// src/components/SeoHowTo.tsx
|
|
822
1474
|
var import_react_helmet_async8 = require("react-helmet-async");
|
|
823
|
-
var
|
|
1475
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
824
1476
|
var SeoHowTo = ({ name, description, image, steps }) => {
|
|
825
1477
|
const schema = {
|
|
826
1478
|
"@context": "https://schema.org",
|
|
@@ -846,12 +1498,12 @@ var SeoHowTo = ({ name, description, image, steps }) => {
|
|
|
846
1498
|
};
|
|
847
1499
|
})
|
|
848
1500
|
};
|
|
849
|
-
return /* @__PURE__ */ (0,
|
|
1501
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_helmet_async8.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
850
1502
|
};
|
|
851
1503
|
|
|
852
1504
|
// src/components/SeoReview.tsx
|
|
853
1505
|
var import_react_helmet_async9 = require("react-helmet-async");
|
|
854
|
-
var
|
|
1506
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
855
1507
|
var SeoReview = ({ itemReviewed, review }) => {
|
|
856
1508
|
const schema = {
|
|
857
1509
|
"@context": "https://schema.org",
|
|
@@ -874,12 +1526,12 @@ var SeoReview = ({ itemReviewed, review }) => {
|
|
|
874
1526
|
"worstRating": review.worstRating || 1
|
|
875
1527
|
}
|
|
876
1528
|
};
|
|
877
|
-
return /* @__PURE__ */ (0,
|
|
1529
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_helmet_async9.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
878
1530
|
};
|
|
879
1531
|
|
|
880
1532
|
// src/components/SeoCourse.tsx
|
|
881
1533
|
var import_react_helmet_async10 = require("react-helmet-async");
|
|
882
|
-
var
|
|
1534
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
883
1535
|
var SeoCourse = ({ course }) => {
|
|
884
1536
|
const schema = {
|
|
885
1537
|
"@context": "https://schema.org",
|
|
@@ -893,12 +1545,12 @@ var SeoCourse = ({ course }) => {
|
|
|
893
1545
|
},
|
|
894
1546
|
"image": course.image
|
|
895
1547
|
};
|
|
896
|
-
return /* @__PURE__ */ (0,
|
|
1548
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_helmet_async10.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
897
1549
|
};
|
|
898
1550
|
|
|
899
1551
|
// src/components/SeoRecipe.tsx
|
|
900
1552
|
var import_react_helmet_async11 = require("react-helmet-async");
|
|
901
|
-
var
|
|
1553
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
902
1554
|
var SeoRecipe = ({ recipe }) => {
|
|
903
1555
|
const schema = {
|
|
904
1556
|
"@context": "https://schema.org",
|
|
@@ -925,12 +1577,12 @@ var SeoRecipe = ({ recipe }) => {
|
|
|
925
1577
|
"image": step.image
|
|
926
1578
|
}))
|
|
927
1579
|
};
|
|
928
|
-
return /* @__PURE__ */ (0,
|
|
1580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_helmet_async11.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
929
1581
|
};
|
|
930
1582
|
|
|
931
1583
|
// src/components/SeoJobPosting.tsx
|
|
932
1584
|
var import_react_helmet_async12 = require("react-helmet-async");
|
|
933
|
-
var
|
|
1585
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
934
1586
|
var SeoJobPosting = ({ job }) => {
|
|
935
1587
|
const schema = {
|
|
936
1588
|
"@context": "https://schema.org",
|
|
@@ -972,11 +1624,12 @@ var SeoJobPosting = ({ job }) => {
|
|
|
972
1624
|
}
|
|
973
1625
|
} : void 0
|
|
974
1626
|
};
|
|
975
|
-
return /* @__PURE__ */ (0,
|
|
1627
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_helmet_async12.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
|
|
976
1628
|
};
|
|
977
1629
|
// Annotate the CommonJS export names for ESM import in node:
|
|
978
1630
|
0 && (module.exports = {
|
|
979
1631
|
Breadcrumb,
|
|
1632
|
+
JsonLd,
|
|
980
1633
|
SEO,
|
|
981
1634
|
SEOProvider,
|
|
982
1635
|
SeoArticle,
|
|
@@ -993,11 +1646,19 @@ var SeoJobPosting = ({ job }) => {
|
|
|
993
1646
|
SeoReview,
|
|
994
1647
|
SeoTag,
|
|
995
1648
|
SeoVideo,
|
|
1649
|
+
cleanSchema,
|
|
1650
|
+
generateArticleMetadata,
|
|
996
1651
|
generateArticleSchema,
|
|
997
1652
|
generateBookSchema,
|
|
998
1653
|
generateBreadcrumbSchema,
|
|
1654
|
+
generateCategoryMetadata,
|
|
1655
|
+
generateCollectionPageSchema,
|
|
999
1656
|
generateEventSchema,
|
|
1000
1657
|
generateFAQSchema,
|
|
1658
|
+
generateHomepageMetadata,
|
|
1659
|
+
generateHowToSchema,
|
|
1660
|
+
generateItemListSchema,
|
|
1661
|
+
generateJobPostingSchema,
|
|
1001
1662
|
generateLocalBusinessSchema,
|
|
1002
1663
|
generateMovieSchema,
|
|
1003
1664
|
generateOrganizationSchema,
|
|
@@ -1005,10 +1666,14 @@ var SeoJobPosting = ({ job }) => {
|
|
|
1005
1666
|
generatePaginationLinks,
|
|
1006
1667
|
generatePodcastEpisodeSchema,
|
|
1007
1668
|
generatePodcastSchema,
|
|
1669
|
+
generateProductMetadata,
|
|
1008
1670
|
generateProductSchema,
|
|
1671
|
+
generateRecipeSchema,
|
|
1009
1672
|
generateSoftwareSchema,
|
|
1010
1673
|
generateVideoSchema,
|
|
1674
|
+
generateWebPageSchema,
|
|
1011
1675
|
generateWebSiteSchema,
|
|
1012
1676
|
toNextMetadata,
|
|
1013
|
-
useSEOConfig
|
|
1677
|
+
useSEOConfig,
|
|
1678
|
+
validateSEO
|
|
1014
1679
|
});
|