@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/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 || config.logo,
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
- return {
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
- return {
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 = "\u0635\u0641\u062D\u0629") {
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 import_jsx_runtime = require("react/jsx-runtime");
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, import_jsx_runtime.jsx)(SEOContext.Provider, { value: { config }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_helmet_async.HelmetProvider, { context: helmetContext, children }) });
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 import_jsx_runtime2 = require("react/jsx-runtime");
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, import_jsx_runtime2.jsxs)(import_react_helmet_async2.Helmet, { children: [
497
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("title", { children: title }),
498
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "description", content: description }),
499
- props.keywords && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "keywords", content: props.keywords.join(", ") }),
500
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "robots", content: props.noindex ? "noindex, nofollow" : props.robots || "index, follow" }),
501
- !props.noindex && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "canonical", href: url }),
502
- props.prev && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "prev", href: props.prev }),
503
- props.next && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "next", href: props.next }),
504
- config.language && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { httpEquiv: "content-language", content: config.language }),
505
- props.alternates?.map((alt, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "alternate", hrefLang: alt.hreflang, href: alt.href }, i)),
506
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:type", content: props.ogType || (props.type === "article" ? "article" : "website") }),
507
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:title", content: props.ogTitle || title }),
508
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:description", content: props.ogDescription || description }),
509
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:image", content: props.ogImage || image }),
510
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:url", content: url }),
511
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:site_name", content: config.name }),
512
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:locale", content: props.ogLocale || config.language || "en_US" }),
513
- config.facebookAppId && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "fb:app_id", content: config.facebookAppId }),
514
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:card", content: props.twitterCard || "summary_large_image" }),
515
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:title", content: props.twitterTitle || title }),
516
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:description", content: props.twitterDescription || description }),
517
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:image", content: props.twitterImage || image }),
518
- config.twitterHandle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:site", content: config.twitterHandle }),
519
- config.twitterHandle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:creator", content: config.twitterHandle }),
520
- props.readingTime && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:label1", content: "Reading time" }),
521
- props.readingTime && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "twitter:data1", content: `${props.readingTime} min` }),
522
- props.type === "article" && props.publishedTime && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "article:published_time", content: props.publishedTime }),
523
- props.type === "article" && props.modifiedTime && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "article:modified_time", content: props.modifiedTime }),
524
- props.type === "article" && props.section && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "article:section", content: props.section }),
525
- props.type === "article" && props.tags?.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "article:tag", content: tag }, tag)),
526
- config.themeColor && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "theme-color", content: config.themeColor }),
527
- config.manifest && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "manifest", href: config.manifest }),
528
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "apple-mobile-web-app-capable", content: "yes" }),
529
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "apple-mobile-web-app-status-bar-style", content: "default" }),
530
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { name: "apple-mobile-web-app-title", content: config.name }),
531
- props.dnsPrefetch?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "dns-prefetch", href: d }, d)),
532
- props.preconnect?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "preconnect", href: d }, d)),
533
- props.prefetch?.map((d) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "prefetch", href: d }, d)),
534
- props.preload?.map((p) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("link", { rel: "preload", href: p.href, as: p.as, type: p.type }, p.href)),
535
- (props.whatsappImage || image) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "og:image:secure_url", content: props.whatsappImage || image }),
536
- props.whatsappDescription && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("meta", { property: "whatsapp:description", content: props.whatsappDescription }),
537
- config.googleAnalyticsId && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("script", { async: true, src: `https://www.googletagmanager.com/gtag/js?id=${config.googleAnalyticsId}` }),
538
- 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}');` }),
539
- schemas.map((schema, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }, index)),
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 import_jsx_runtime3 = require("react/jsx-runtime");
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, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
564
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_helmet_async3.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) }),
565
- /* @__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) => {
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, import_jsx_runtime3.jsxs)("li", { style: { display: "flex", alignItems: "center" }, children: [
568
- 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 }),
569
- !isLast && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { margin: "0 8px" }, children: separator })
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 import_jsx_runtime4 = require("react/jsx-runtime");
1207
+ var import_jsx_runtime5 = require("react/jsx-runtime");
577
1208
  var SeoArticle = ({ article, ...rest }) => {
578
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
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 import_jsx_runtime5 = require("react/jsx-runtime");
1227
+ var import_jsx_runtime6 = require("react/jsx-runtime");
597
1228
  var SeoProduct = ({ item, ...rest }) => {
598
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
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 import_jsx_runtime6 = require("react/jsx-runtime");
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, import_jsx_runtime6.jsx)(import_react_helmet_async4.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
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 import_jsx_runtime7 = require("react/jsx-runtime");
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, import_jsx_runtime7.jsx)(import_react_helmet_async5.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
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 import_jsx_runtime8 = require("react/jsx-runtime");
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, import_jsx_runtime8.jsx)(import_react_helmet_async6.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
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 import_jsx_runtime9 = require("react/jsx-runtime");
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, import_jsx_runtime9.jsx)(import_react_helmet_async7.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
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 import_jsx_runtime10 = require("react/jsx-runtime");
736
- var SeoCategory = ({ category, page = 1, totalPage = 1, ...rest }) => {
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, import_jsx_runtime10.jsx)(
1380
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
744
1381
  SEO,
745
1382
  {
746
1383
  type: "website",
747
- title: `${category.name}${page > 1 ? ` - \u0635\u0641\u062D\u0629 ${page}` : ""}`,
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 import_jsx_runtime11 = require("react/jsx-runtime");
767
- var SeoTag = ({ tag, page = 1, totalPage = 1, ...rest }) => {
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
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
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: `\u062A\u0627\u063A: ${tag.name}${page > 1 ? ` - \u0635\u0641\u062D\u0629 ${page}` : ""}`,
779
- 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}`,
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 import_jsx_runtime12 = require("react/jsx-runtime");
790
- var SeoAuthor = ({ author, page = 1, totalPage = 1, ...rest }) => {
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, import_jsx_runtime12.jsx)(
1449
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
798
1450
  SEO,
799
1451
  {
800
1452
  type: "profile",
801
- title: `${author.name}${page > 1 ? ` - \u0635\u0641\u062D\u0629 ${page}` : ""}`,
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 import_jsx_runtime13 = require("react/jsx-runtime");
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, import_jsx_runtime13.jsx)(import_react_helmet_async8.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
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 import_jsx_runtime14 = require("react/jsx-runtime");
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, import_jsx_runtime14.jsx)(import_react_helmet_async9.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
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 import_jsx_runtime15 = require("react/jsx-runtime");
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, import_jsx_runtime15.jsx)(import_react_helmet_async10.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
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 import_jsx_runtime16 = require("react/jsx-runtime");
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, import_jsx_runtime16.jsx)(import_react_helmet_async11.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
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 import_jsx_runtime17 = require("react/jsx-runtime");
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, import_jsx_runtime17.jsx)(import_react_helmet_async12.Helmet, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("script", { type: "application/ld+json", children: JSON.stringify(schema) }) });
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
  });