react-ssr-seo-toolkit 1.1.0 → 1.2.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.
Files changed (70) hide show
  1. package/README.md +592 -512
  2. package/dist/adapters/nextjs.d.cts +1 -1
  3. package/dist/adapters/nextjs.d.ts +1 -1
  4. package/dist/adapters/react-router.d.cts +1 -1
  5. package/dist/adapters/react-router.d.ts +1 -1
  6. package/dist/chunk-3UCLUFOI.js +5 -0
  7. package/dist/chunk-3UCLUFOI.js.map +1 -0
  8. package/dist/chunk-A62THBIS.cjs +3 -0
  9. package/dist/chunk-A62THBIS.cjs.map +1 -0
  10. package/dist/chunk-GNLXGAS6.js +3 -0
  11. package/dist/chunk-GNLXGAS6.js.map +1 -0
  12. package/dist/chunk-LEOORZQY.cjs +5 -0
  13. package/dist/chunk-LEOORZQY.cjs.map +1 -0
  14. package/dist/chunk-ROA74LH6.cjs +61 -0
  15. package/dist/chunk-ROA74LH6.cjs.map +1 -0
  16. package/dist/chunk-WM5VVPED.js +61 -0
  17. package/dist/chunk-WM5VVPED.js.map +1 -0
  18. package/dist/chunk-X535MU7Z.js +5 -0
  19. package/dist/chunk-X535MU7Z.js.map +1 -0
  20. package/dist/chunk-ZADUJHVR.cjs +5 -0
  21. package/dist/chunk-ZADUJHVR.cjs.map +1 -0
  22. package/dist/chunk-ZECSTNEE.cjs +3 -0
  23. package/dist/chunk-ZECSTNEE.cjs.map +1 -0
  24. package/dist/chunk-ZVFEGG25.js +3 -0
  25. package/dist/chunk-ZVFEGG25.js.map +1 -0
  26. package/dist/components.cjs +1 -1
  27. package/dist/components.d.cts +2 -2
  28. package/dist/components.d.ts +2 -2
  29. package/dist/components.js +1 -1
  30. package/dist/index-Br7Sh9Ur.d.cts +329 -0
  31. package/dist/index-Br7Sh9Ur.d.ts +329 -0
  32. package/dist/{index-DAGfo2Fc.d.ts → index-CKNcgAj8.d.ts} +10 -2
  33. package/dist/{index-RBSUcdqN.d.cts → index-Wgogf4CX.d.cts} +10 -2
  34. package/dist/index.cjs +1 -1
  35. package/dist/index.d.cts +7 -4
  36. package/dist/index.d.ts +7 -4
  37. package/dist/index.js +1 -1
  38. package/dist/og.cjs +2 -0
  39. package/dist/og.cjs.map +1 -0
  40. package/dist/og.d.cts +5 -0
  41. package/dist/og.d.ts +5 -0
  42. package/dist/og.js +2 -0
  43. package/dist/og.js.map +1 -0
  44. package/dist/schema.cjs +1 -1
  45. package/dist/schema.d.cts +6 -2
  46. package/dist/schema.d.ts +6 -2
  47. package/dist/schema.js +1 -1
  48. package/dist/sitemap.cjs +2 -0
  49. package/dist/sitemap.cjs.map +1 -0
  50. package/dist/sitemap.d.cts +12 -0
  51. package/dist/sitemap.d.ts +12 -0
  52. package/dist/sitemap.js +2 -0
  53. package/dist/sitemap.js.map +1 -0
  54. package/dist/validation.cjs +2 -0
  55. package/dist/validation.cjs.map +1 -0
  56. package/dist/validation.d.cts +8 -0
  57. package/dist/validation.d.ts +8 -0
  58. package/dist/validation.js +2 -0
  59. package/dist/validation.js.map +1 -0
  60. package/package.json +38 -2
  61. package/dist/chunk-63ETSZTD.cjs +0 -3
  62. package/dist/chunk-63ETSZTD.cjs.map +0 -1
  63. package/dist/chunk-AYIAPQTP.js +0 -2
  64. package/dist/chunk-AYIAPQTP.js.map +0 -1
  65. package/dist/chunk-ES4OXVOR.js +0 -3
  66. package/dist/chunk-ES4OXVOR.js.map +0 -1
  67. package/dist/chunk-T7EB7Y2S.cjs +0 -2
  68. package/dist/chunk-T7EB7Y2S.cjs.map +0 -1
  69. package/dist/index-Dr2yktvz.d.cts +0 -136
  70. package/dist/index-Dr2yktvz.d.ts +0 -136
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-ssr-seo-toolkit",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Framework-agnostic SEO utilities, metadata builders, structured data helpers, and React components for SSR applications",
5
5
  "keywords": [
6
6
  "seo",
@@ -18,7 +18,13 @@
18
18
  "schema-org",
19
19
  "breadcrumb",
20
20
  "hreflang",
21
- "server-side-rendering"
21
+ "server-side-rendering",
22
+ "sitemap",
23
+ "robots-txt",
24
+ "seo-validation",
25
+ "og-image",
26
+ "seo-score",
27
+ "social-preview"
22
28
  ],
23
29
  "author": "tonmoy1996",
24
30
  "license": "MIT",
@@ -65,6 +71,36 @@
65
71
  "default": "./dist/components.cjs"
66
72
  }
67
73
  },
74
+ "./sitemap": {
75
+ "import": {
76
+ "types": "./dist/sitemap.d.ts",
77
+ "default": "./dist/sitemap.js"
78
+ },
79
+ "require": {
80
+ "types": "./dist/sitemap.d.cts",
81
+ "default": "./dist/sitemap.cjs"
82
+ }
83
+ },
84
+ "./validation": {
85
+ "import": {
86
+ "types": "./dist/validation.d.ts",
87
+ "default": "./dist/validation.js"
88
+ },
89
+ "require": {
90
+ "types": "./dist/validation.d.cts",
91
+ "default": "./dist/validation.cjs"
92
+ }
93
+ },
94
+ "./og": {
95
+ "import": {
96
+ "types": "./dist/og.d.ts",
97
+ "default": "./dist/og.js"
98
+ },
99
+ "require": {
100
+ "types": "./dist/og.d.cts",
101
+ "default": "./dist/og.cjs"
102
+ }
103
+ },
68
104
  "./adapters/nextjs": {
69
105
  "import": {
70
106
  "types": "./dist/adapters/nextjs.d.ts",
@@ -1,3 +0,0 @@
1
- 'use strict';var r="https://schema.org";function n(e){let a={"@context":r,"@type":"Organization",name:e.name,url:e.url};if(e.logo&&(a.logo=e.logo),e.description&&(a.description=e.description),e.sameAs?.length&&(a.sameAs=e.sameAs),e.contactPoint){let t={"@type":"ContactPoint"};e.contactPoint.telephone&&(t.telephone=e.contactPoint.telephone),e.contactPoint.contactType&&(t.contactType=e.contactPoint.contactType),e.contactPoint.email&&(t.email=e.contactPoint.email),e.contactPoint.areaServed&&(t.areaServed=e.contactPoint.areaServed),e.contactPoint.availableLanguage&&(t.availableLanguage=e.contactPoint.availableLanguage),a.contactPoint=t;}return a}function i(e){let a={"@context":r,"@type":"WebSite",name:e.name,url:e.url};return e.description&&(a.description=e.description),e.searchUrl&&(a.potentialAction={"@type":"SearchAction",target:{"@type":"EntryPoint",urlTemplate:`${e.searchUrl}?${e.searchQueryParam??"q"}={search_term_string}`},"query-input":"required name=search_term_string"}),a}function s(e){return {"@context":r,"@type":"BreadcrumbList",itemListElement:e.map((a,t)=>({"@type":"ListItem",position:t+1,name:a.name,item:a.url}))}}function m(e){let a={"@context":r,"@type":"Article",headline:e.headline,url:e.url};if(e.description&&(a.description=e.description),e.images?.length&&(a.image=e.images),e.datePublished&&(a.datePublished=e.datePublished),e.dateModified&&(a.dateModified=e.dateModified),e.section&&(a.articleSection=e.section),e.keywords?.length&&(a.keywords=e.keywords),e.author){let t=Array.isArray(e.author)?e.author:[e.author];a.author=t.map(o=>{let c={"@type":"Person",name:o.name};return o.url&&(c.url=o.url),c});}if(e.publisher){let t={"@type":"Organization",name:e.publisher.name};e.publisher.logo&&(t.logo={"@type":"ImageObject",url:e.publisher.logo}),a.publisher=t;}return a}function l(e){let a={"@context":r,"@type":"Product",name:e.name,url:e.url};if(e.description&&(a.description=e.description),e.images?.length&&(a.image=e.images),e.brand&&(a.brand={"@type":"Brand",name:e.brand}),e.sku&&(a.sku=e.sku),e.gtin&&(a.gtin=e.gtin),e.price!==void 0){let t={"@type":"Offer",price:e.price,priceCurrency:e.priceCurrency??"USD"};e.availability&&(t.availability=`https://schema.org/${e.availability}`),a.offers=t;}if(e.ratingValue!==void 0){let t={"@type":"AggregateRating",ratingValue:e.ratingValue};e.reviewCount!==void 0&&(t.reviewCount=e.reviewCount),a.aggregateRating=t;}return a}function d(e){return {"@context":r,"@type":"FAQPage",mainEntity:e.map(a=>({"@type":"Question",name:a.question,acceptedAnswer:{"@type":"Answer",text:a.answer}}))}}function g(...e){return {"@context":r,"@type":"ItemList","@graph":e.map(({"@context":a,...t})=>t)}}
2
- exports.a=n;exports.b=i;exports.c=s;exports.d=m;exports.e=l;exports.f=d;exports.g=g;//# sourceMappingURL=chunk-63ETSZTD.cjs.map
3
- //# sourceMappingURL=chunk-63ETSZTD.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schema/index.ts"],"names":["CONTEXT","createOrganizationSchema","input","schema","cp","createWebsiteSchema","createBreadcrumbSchema","items","item","index","createArticleSchema","authors","a","person","pub","createProductSchema","offer","rating","createFAQSchema","composeSchemas","schemas","_ctx","rest"],"mappings":"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","file":"chunk-63ETSZTD.cjs","sourcesContent":["import type {\n JSONLDBase,\n BreadcrumbItem,\n OrganizationSchemaInput,\n WebsiteSchemaInput,\n ArticleSchemaInput,\n ProductSchemaInput,\n FAQItem,\n} from \"../types/index.js\";\n\nconst CONTEXT = \"https://schema.org\";\n\n// ─── Organization ─────────────────────────────────────────────\n\nexport function createOrganizationSchema(\n input: OrganizationSchemaInput\n): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Organization\",\n name: input.name,\n url: input.url,\n };\n\n if (input.logo) schema.logo = input.logo;\n if (input.description) schema.description = input.description;\n if (input.sameAs?.length) schema.sameAs = input.sameAs;\n\n if (input.contactPoint) {\n const cp: Record<string, unknown> = {\n \"@type\": \"ContactPoint\",\n };\n if (input.contactPoint.telephone)\n cp.telephone = input.contactPoint.telephone;\n if (input.contactPoint.contactType)\n cp.contactType = input.contactPoint.contactType;\n if (input.contactPoint.email) cp.email = input.contactPoint.email;\n if (input.contactPoint.areaServed)\n cp.areaServed = input.contactPoint.areaServed;\n if (input.contactPoint.availableLanguage)\n cp.availableLanguage = input.contactPoint.availableLanguage;\n schema.contactPoint = cp;\n }\n\n return schema;\n}\n\n// ─── Website ──────────────────────────────────────────────────\n\nexport function createWebsiteSchema(input: WebsiteSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"WebSite\",\n name: input.name,\n url: input.url,\n };\n\n if (input.description) schema.description = input.description;\n\n if (input.searchUrl) {\n schema.potentialAction = {\n \"@type\": \"SearchAction\",\n target: {\n \"@type\": \"EntryPoint\",\n urlTemplate: `${input.searchUrl}?${input.searchQueryParam ?? \"q\"}={search_term_string}`,\n },\n \"query-input\": \"required name=search_term_string\",\n };\n }\n\n return schema;\n}\n\n// ─── Breadcrumb ───────────────────────────────────────────────\n\nexport function createBreadcrumbSchema(items: BreadcrumbItem[]): JSONLDBase {\n return {\n \"@context\": CONTEXT,\n \"@type\": \"BreadcrumbList\",\n itemListElement: items.map((item, index) => ({\n \"@type\": \"ListItem\",\n position: index + 1,\n name: item.name,\n item: item.url,\n })),\n };\n}\n\n// ─── Article ──────────────────────────────────────────────────\n\nexport function createArticleSchema(input: ArticleSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Article\",\n headline: input.headline,\n url: input.url,\n };\n\n if (input.description) schema.description = input.description;\n if (input.images?.length) schema.image = input.images;\n if (input.datePublished) schema.datePublished = input.datePublished;\n if (input.dateModified) schema.dateModified = input.dateModified;\n if (input.section) schema.articleSection = input.section;\n if (input.keywords?.length) schema.keywords = input.keywords;\n\n if (input.author) {\n const authors = Array.isArray(input.author)\n ? input.author\n : [input.author];\n schema.author = authors.map((a) => {\n const person: Record<string, string> = {\n \"@type\": \"Person\",\n name: a.name,\n };\n if (a.url) person.url = a.url;\n return person;\n });\n }\n\n if (input.publisher) {\n const pub: Record<string, unknown> = {\n \"@type\": \"Organization\",\n name: input.publisher.name,\n };\n if (input.publisher.logo) {\n pub.logo = {\n \"@type\": \"ImageObject\",\n url: input.publisher.logo,\n };\n }\n schema.publisher = pub;\n }\n\n return schema;\n}\n\n// ─── Product ──────────────────────────────────────────────────\n\nexport function createProductSchema(input: ProductSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Product\",\n name: input.name,\n url: input.url,\n };\n\n if (input.description) schema.description = input.description;\n if (input.images?.length) schema.image = input.images;\n if (input.brand) {\n schema.brand = { \"@type\": \"Brand\", name: input.brand };\n }\n if (input.sku) schema.sku = input.sku;\n if (input.gtin) schema.gtin = input.gtin;\n\n if (input.price !== undefined) {\n const offer: Record<string, unknown> = {\n \"@type\": \"Offer\",\n price: input.price,\n priceCurrency: input.priceCurrency ?? \"USD\",\n };\n if (input.availability) {\n offer.availability = `https://schema.org/${input.availability}`;\n }\n schema.offers = offer;\n }\n\n if (input.ratingValue !== undefined) {\n const rating: Record<string, unknown> = {\n \"@type\": \"AggregateRating\",\n ratingValue: input.ratingValue,\n };\n if (input.reviewCount !== undefined) rating.reviewCount = input.reviewCount;\n schema.aggregateRating = rating;\n }\n\n return schema;\n}\n\n// ─── FAQ ──────────────────────────────────────────────────────\n\nexport function createFAQSchema(items: FAQItem[]): JSONLDBase {\n return {\n \"@context\": CONTEXT,\n \"@type\": \"FAQPage\",\n mainEntity: items.map((item) => ({\n \"@type\": \"Question\",\n name: item.question,\n acceptedAnswer: {\n \"@type\": \"Answer\",\n text: item.answer,\n },\n })),\n };\n}\n\n// ─── Schema composition ───────────────────────────────────────\n\n/**\n * Compose multiple JSON-LD schemas into a single @graph array.\n * Useful for embedding multiple structured data blocks in one script tag.\n */\nexport function composeSchemas(...schemas: JSONLDBase[]): JSONLDBase {\n return {\n \"@context\": CONTEXT,\n \"@type\": \"ItemList\",\n \"@graph\": schemas.map(({ \"@context\": _ctx, ...rest }) => rest),\n };\n}\n"]}
@@ -1,2 +0,0 @@
1
- import {i,l,o,p,q,a}from'./chunk-LP66SUGR.js';import t from'react';function C({title:c,titleTemplate:i$1,description:m,canonical:p$1,robots:R,openGraph:S,twitter:b,alternates:x,additionalMetaTags:l$1,additionalLinkTags:f,jsonLd:s,nonce:L}){let n=[],O=0,r=()=>`seo-${O++}`,y=i(c,i$1);y&&n.push(t.createElement("title",{key:r()},y)),m?.trim()&&n.push(t.createElement("meta",{key:r(),name:"description",content:m.trim()})),p$1?.trim()&&n.push(t.createElement("link",{key:r(),rel:"canonical",href:p$1.trim()}));let u=l(R);u&&n.push(t.createElement("meta",{key:r(),name:"robots",content:u}));let H=o(S);for(let e of H)n.push(t.createElement("meta",{key:r(),property:e.property,content:e.content}));let J=p(b);for(let e of J)n.push(t.createElement("meta",{key:r(),name:e.name,content:e.content}));let T=q(x);for(let e of T)n.push(t.createElement("link",{key:r(),rel:e.rel,hrefLang:e.hreflang,href:e.href}));if(l$1)for(let e of l$1){let o={content:e.content};e.name&&(o.name=e.name),e.property&&(o.property=e.property),n.push(t.createElement("meta",{key:r(),...o}));}if(f)for(let e of f)n.push(t.createElement("link",{key:r(),...e}));if(s){let e=Array.isArray(s)?s:[s];for(let o of e)n.push(t.createElement("script",{key:r(),type:"application/ld+json",nonce:L,dangerouslySetInnerHTML:{__html:a(o)}}));}return t.createElement(t.Fragment,null,...n)}function M({data:c,nonce:i}){return t.createElement("script",{type:"application/ld+json",nonce:i,dangerouslySetInnerHTML:{__html:a(c)}})}export{C as a,M as b};//# sourceMappingURL=chunk-AYIAPQTP.js.map
2
- //# sourceMappingURL=chunk-AYIAPQTP.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/SEOHead.tsx","../src/components/JsonLd.tsx"],"names":["SEOHead","title","titleTemplate","description","canonical","robots","openGraph","twitter","alternates","additionalMetaTags","additionalLinkTags","jsonLd","nonce","elements","key","k","resolvedTitle","buildTitle","React","robotsContent","buildRobotsDirectives","ogTags","buildOpenGraph","tag","twitterTags","buildTwitterMetadata","altLinks","buildAlternateLinks","link","meta","props","schemas","schema","safeJsonLdSerialize","JsonLd","data"],"mappings":"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","file":"chunk-AYIAPQTP.js","sourcesContent":["import React from \"react\";\nimport type { SEOConfig } from \"../types/index.js\";\nimport {\n buildTitle,\n buildRobotsDirectives,\n buildOpenGraph,\n buildTwitterMetadata,\n buildAlternateLinks,\n} from \"../core/index.js\";\nimport { safeJsonLdSerialize } from \"../utils/index.js\";\n\nexport interface SEOHeadProps extends SEOConfig {\n /**\n * Optional nonce for CSP-compatible script tags.\n */\n nonce?: string;\n}\n\n/**\n * Generic SSR-safe React component that renders SEO-related tags.\n *\n * Renders: title, meta description, canonical link, robots meta,\n * Open Graph tags, Twitter tags, alternate/hreflang links,\n * additional meta/link tags, and JSON-LD scripts.\n *\n * Designed to be placed inside a <head> element in SSR apps.\n * Does NOT use any browser globals — fully SSR-compatible.\n */\nexport function SEOHead({\n title,\n titleTemplate,\n description,\n canonical,\n robots,\n openGraph,\n twitter,\n alternates,\n additionalMetaTags,\n additionalLinkTags,\n jsonLd,\n nonce,\n}: SEOHeadProps): React.ReactElement {\n const elements: React.ReactElement[] = [];\n let key = 0;\n const k = () => `seo-${key++}`;\n\n // Title\n const resolvedTitle = buildTitle(title, titleTemplate);\n if (resolvedTitle) {\n elements.push(React.createElement(\"title\", { key: k() }, resolvedTitle));\n }\n\n // Description\n if (description?.trim()) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n name: \"description\",\n content: description.trim(),\n })\n );\n }\n\n // Canonical\n if (canonical?.trim()) {\n elements.push(\n React.createElement(\"link\", {\n key: k(),\n rel: \"canonical\",\n href: canonical.trim(),\n })\n );\n }\n\n // Robots\n const robotsContent = buildRobotsDirectives(robots);\n if (robotsContent) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n name: \"robots\",\n content: robotsContent,\n })\n );\n }\n\n // Open Graph\n const ogTags = buildOpenGraph(openGraph);\n for (const tag of ogTags) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n property: tag.property,\n content: tag.content,\n })\n );\n }\n\n // Twitter\n const twitterTags = buildTwitterMetadata(twitter);\n for (const tag of twitterTags) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n name: tag.name,\n content: tag.content,\n })\n );\n }\n\n // Hreflang alternates\n const altLinks = buildAlternateLinks(alternates);\n for (const link of altLinks) {\n elements.push(\n React.createElement(\"link\", {\n key: k(),\n rel: link.rel,\n hrefLang: link.hreflang,\n href: link.href,\n })\n );\n }\n\n // Additional meta tags\n if (additionalMetaTags) {\n for (const meta of additionalMetaTags) {\n const props: Record<string, string> = { content: meta.content };\n if (meta.name) props.name = meta.name;\n if (meta.property) props.property = meta.property;\n elements.push(React.createElement(\"meta\", { key: k(), ...props }));\n }\n }\n\n // Additional link tags\n if (additionalLinkTags) {\n for (const link of additionalLinkTags) {\n elements.push(React.createElement(\"link\", { key: k(), ...link }));\n }\n }\n\n // JSON-LD\n if (jsonLd) {\n const schemas = Array.isArray(jsonLd) ? jsonLd : [jsonLd];\n for (const schema of schemas) {\n elements.push(\n React.createElement(\"script\", {\n key: k(),\n type: \"application/ld+json\",\n nonce,\n dangerouslySetInnerHTML: {\n __html: safeJsonLdSerialize(schema),\n },\n })\n );\n }\n }\n\n return React.createElement(React.Fragment, null, ...elements);\n}\n","import React from \"react\";\nimport { safeJsonLdSerialize } from \"../utils/index.js\";\n\nexport interface JsonLdProps {\n data: Record<string, unknown> | Array<Record<string, unknown>>;\n nonce?: string;\n}\n\n/**\n * Renders a <script type=\"application/ld+json\"> tag with safely serialized JSON-LD.\n * SSR-safe: no browser globals used.\n */\nexport function JsonLd({ data, nonce }: JsonLdProps): React.ReactElement {\n return React.createElement(\"script\", {\n type: \"application/ld+json\",\n nonce,\n dangerouslySetInnerHTML: {\n __html: safeJsonLdSerialize(data),\n },\n });\n}\n"]}
@@ -1,3 +0,0 @@
1
- var r="https://schema.org";function n(e){let a={"@context":r,"@type":"Organization",name:e.name,url:e.url};if(e.logo&&(a.logo=e.logo),e.description&&(a.description=e.description),e.sameAs?.length&&(a.sameAs=e.sameAs),e.contactPoint){let t={"@type":"ContactPoint"};e.contactPoint.telephone&&(t.telephone=e.contactPoint.telephone),e.contactPoint.contactType&&(t.contactType=e.contactPoint.contactType),e.contactPoint.email&&(t.email=e.contactPoint.email),e.contactPoint.areaServed&&(t.areaServed=e.contactPoint.areaServed),e.contactPoint.availableLanguage&&(t.availableLanguage=e.contactPoint.availableLanguage),a.contactPoint=t;}return a}function i(e){let a={"@context":r,"@type":"WebSite",name:e.name,url:e.url};return e.description&&(a.description=e.description),e.searchUrl&&(a.potentialAction={"@type":"SearchAction",target:{"@type":"EntryPoint",urlTemplate:`${e.searchUrl}?${e.searchQueryParam??"q"}={search_term_string}`},"query-input":"required name=search_term_string"}),a}function s(e){return {"@context":r,"@type":"BreadcrumbList",itemListElement:e.map((a,t)=>({"@type":"ListItem",position:t+1,name:a.name,item:a.url}))}}function m(e){let a={"@context":r,"@type":"Article",headline:e.headline,url:e.url};if(e.description&&(a.description=e.description),e.images?.length&&(a.image=e.images),e.datePublished&&(a.datePublished=e.datePublished),e.dateModified&&(a.dateModified=e.dateModified),e.section&&(a.articleSection=e.section),e.keywords?.length&&(a.keywords=e.keywords),e.author){let t=Array.isArray(e.author)?e.author:[e.author];a.author=t.map(o=>{let c={"@type":"Person",name:o.name};return o.url&&(c.url=o.url),c});}if(e.publisher){let t={"@type":"Organization",name:e.publisher.name};e.publisher.logo&&(t.logo={"@type":"ImageObject",url:e.publisher.logo}),a.publisher=t;}return a}function l(e){let a={"@context":r,"@type":"Product",name:e.name,url:e.url};if(e.description&&(a.description=e.description),e.images?.length&&(a.image=e.images),e.brand&&(a.brand={"@type":"Brand",name:e.brand}),e.sku&&(a.sku=e.sku),e.gtin&&(a.gtin=e.gtin),e.price!==void 0){let t={"@type":"Offer",price:e.price,priceCurrency:e.priceCurrency??"USD"};e.availability&&(t.availability=`https://schema.org/${e.availability}`),a.offers=t;}if(e.ratingValue!==void 0){let t={"@type":"AggregateRating",ratingValue:e.ratingValue};e.reviewCount!==void 0&&(t.reviewCount=e.reviewCount),a.aggregateRating=t;}return a}function d(e){return {"@context":r,"@type":"FAQPage",mainEntity:e.map(a=>({"@type":"Question",name:a.question,acceptedAnswer:{"@type":"Answer",text:a.answer}}))}}function g(...e){return {"@context":r,"@type":"ItemList","@graph":e.map(({"@context":a,...t})=>t)}}
2
- export{n as a,i as b,s as c,m as d,l as e,d as f,g};//# sourceMappingURL=chunk-ES4OXVOR.js.map
3
- //# sourceMappingURL=chunk-ES4OXVOR.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schema/index.ts"],"names":["CONTEXT","createOrganizationSchema","input","schema","cp","createWebsiteSchema","createBreadcrumbSchema","items","item","index","createArticleSchema","authors","a","person","pub","createProductSchema","offer","rating","createFAQSchema","composeSchemas","schemas","_ctx","rest"],"mappings":"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","file":"chunk-ES4OXVOR.js","sourcesContent":["import type {\n JSONLDBase,\n BreadcrumbItem,\n OrganizationSchemaInput,\n WebsiteSchemaInput,\n ArticleSchemaInput,\n ProductSchemaInput,\n FAQItem,\n} from \"../types/index.js\";\n\nconst CONTEXT = \"https://schema.org\";\n\n// ─── Organization ─────────────────────────────────────────────\n\nexport function createOrganizationSchema(\n input: OrganizationSchemaInput\n): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Organization\",\n name: input.name,\n url: input.url,\n };\n\n if (input.logo) schema.logo = input.logo;\n if (input.description) schema.description = input.description;\n if (input.sameAs?.length) schema.sameAs = input.sameAs;\n\n if (input.contactPoint) {\n const cp: Record<string, unknown> = {\n \"@type\": \"ContactPoint\",\n };\n if (input.contactPoint.telephone)\n cp.telephone = input.contactPoint.telephone;\n if (input.contactPoint.contactType)\n cp.contactType = input.contactPoint.contactType;\n if (input.contactPoint.email) cp.email = input.contactPoint.email;\n if (input.contactPoint.areaServed)\n cp.areaServed = input.contactPoint.areaServed;\n if (input.contactPoint.availableLanguage)\n cp.availableLanguage = input.contactPoint.availableLanguage;\n schema.contactPoint = cp;\n }\n\n return schema;\n}\n\n// ─── Website ──────────────────────────────────────────────────\n\nexport function createWebsiteSchema(input: WebsiteSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"WebSite\",\n name: input.name,\n url: input.url,\n };\n\n if (input.description) schema.description = input.description;\n\n if (input.searchUrl) {\n schema.potentialAction = {\n \"@type\": \"SearchAction\",\n target: {\n \"@type\": \"EntryPoint\",\n urlTemplate: `${input.searchUrl}?${input.searchQueryParam ?? \"q\"}={search_term_string}`,\n },\n \"query-input\": \"required name=search_term_string\",\n };\n }\n\n return schema;\n}\n\n// ─── Breadcrumb ───────────────────────────────────────────────\n\nexport function createBreadcrumbSchema(items: BreadcrumbItem[]): JSONLDBase {\n return {\n \"@context\": CONTEXT,\n \"@type\": \"BreadcrumbList\",\n itemListElement: items.map((item, index) => ({\n \"@type\": \"ListItem\",\n position: index + 1,\n name: item.name,\n item: item.url,\n })),\n };\n}\n\n// ─── Article ──────────────────────────────────────────────────\n\nexport function createArticleSchema(input: ArticleSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Article\",\n headline: input.headline,\n url: input.url,\n };\n\n if (input.description) schema.description = input.description;\n if (input.images?.length) schema.image = input.images;\n if (input.datePublished) schema.datePublished = input.datePublished;\n if (input.dateModified) schema.dateModified = input.dateModified;\n if (input.section) schema.articleSection = input.section;\n if (input.keywords?.length) schema.keywords = input.keywords;\n\n if (input.author) {\n const authors = Array.isArray(input.author)\n ? input.author\n : [input.author];\n schema.author = authors.map((a) => {\n const person: Record<string, string> = {\n \"@type\": \"Person\",\n name: a.name,\n };\n if (a.url) person.url = a.url;\n return person;\n });\n }\n\n if (input.publisher) {\n const pub: Record<string, unknown> = {\n \"@type\": \"Organization\",\n name: input.publisher.name,\n };\n if (input.publisher.logo) {\n pub.logo = {\n \"@type\": \"ImageObject\",\n url: input.publisher.logo,\n };\n }\n schema.publisher = pub;\n }\n\n return schema;\n}\n\n// ─── Product ──────────────────────────────────────────────────\n\nexport function createProductSchema(input: ProductSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Product\",\n name: input.name,\n url: input.url,\n };\n\n if (input.description) schema.description = input.description;\n if (input.images?.length) schema.image = input.images;\n if (input.brand) {\n schema.brand = { \"@type\": \"Brand\", name: input.brand };\n }\n if (input.sku) schema.sku = input.sku;\n if (input.gtin) schema.gtin = input.gtin;\n\n if (input.price !== undefined) {\n const offer: Record<string, unknown> = {\n \"@type\": \"Offer\",\n price: input.price,\n priceCurrency: input.priceCurrency ?? \"USD\",\n };\n if (input.availability) {\n offer.availability = `https://schema.org/${input.availability}`;\n }\n schema.offers = offer;\n }\n\n if (input.ratingValue !== undefined) {\n const rating: Record<string, unknown> = {\n \"@type\": \"AggregateRating\",\n ratingValue: input.ratingValue,\n };\n if (input.reviewCount !== undefined) rating.reviewCount = input.reviewCount;\n schema.aggregateRating = rating;\n }\n\n return schema;\n}\n\n// ─── FAQ ──────────────────────────────────────────────────────\n\nexport function createFAQSchema(items: FAQItem[]): JSONLDBase {\n return {\n \"@context\": CONTEXT,\n \"@type\": \"FAQPage\",\n mainEntity: items.map((item) => ({\n \"@type\": \"Question\",\n name: item.question,\n acceptedAnswer: {\n \"@type\": \"Answer\",\n text: item.answer,\n },\n })),\n };\n}\n\n// ─── Schema composition ───────────────────────────────────────\n\n/**\n * Compose multiple JSON-LD schemas into a single @graph array.\n * Useful for embedding multiple structured data blocks in one script tag.\n */\nexport function composeSchemas(...schemas: JSONLDBase[]): JSONLDBase {\n return {\n \"@context\": CONTEXT,\n \"@type\": \"ItemList\",\n \"@graph\": schemas.map(({ \"@context\": _ctx, ...rest }) => rest),\n };\n}\n"]}
@@ -1,2 +0,0 @@
1
- 'use strict';var chunkFKDMHECL_cjs=require('./chunk-FKDMHECL.cjs'),t=require('react');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var t__default=/*#__PURE__*/_interopDefault(t);function C({title:c,titleTemplate:i,description:m,canonical:p,robots:R,openGraph:S,twitter:b,alternates:x,additionalMetaTags:l,additionalLinkTags:f,jsonLd:s,nonce:L}){let n=[],O=0,r=()=>`seo-${O++}`,y=chunkFKDMHECL_cjs.i(c,i);y&&n.push(t__default.default.createElement("title",{key:r()},y)),m?.trim()&&n.push(t__default.default.createElement("meta",{key:r(),name:"description",content:m.trim()})),p?.trim()&&n.push(t__default.default.createElement("link",{key:r(),rel:"canonical",href:p.trim()}));let u=chunkFKDMHECL_cjs.l(R);u&&n.push(t__default.default.createElement("meta",{key:r(),name:"robots",content:u}));let H=chunkFKDMHECL_cjs.o(S);for(let e of H)n.push(t__default.default.createElement("meta",{key:r(),property:e.property,content:e.content}));let J=chunkFKDMHECL_cjs.p(b);for(let e of J)n.push(t__default.default.createElement("meta",{key:r(),name:e.name,content:e.content}));let T=chunkFKDMHECL_cjs.q(x);for(let e of T)n.push(t__default.default.createElement("link",{key:r(),rel:e.rel,hrefLang:e.hreflang,href:e.href}));if(l)for(let e of l){let o={content:e.content};e.name&&(o.name=e.name),e.property&&(o.property=e.property),n.push(t__default.default.createElement("meta",{key:r(),...o}));}if(f)for(let e of f)n.push(t__default.default.createElement("link",{key:r(),...e}));if(s){let e=Array.isArray(s)?s:[s];for(let o of e)n.push(t__default.default.createElement("script",{key:r(),type:"application/ld+json",nonce:L,dangerouslySetInnerHTML:{__html:chunkFKDMHECL_cjs.a(o)}}));}return t__default.default.createElement(t__default.default.Fragment,null,...n)}function M({data:c,nonce:i}){return t__default.default.createElement("script",{type:"application/ld+json",nonce:i,dangerouslySetInnerHTML:{__html:chunkFKDMHECL_cjs.a(c)}})}exports.a=C;exports.b=M;//# sourceMappingURL=chunk-T7EB7Y2S.cjs.map
2
- //# sourceMappingURL=chunk-T7EB7Y2S.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/SEOHead.tsx","../src/components/JsonLd.tsx"],"names":["SEOHead","title","titleTemplate","description","canonical","robots","openGraph","twitter","alternates","additionalMetaTags","additionalLinkTags","jsonLd","nonce","elements","key","k","resolvedTitle","buildTitle","React","robotsContent","buildRobotsDirectives","ogTags","buildOpenGraph","tag","twitterTags","buildTwitterMetadata","altLinks","buildAlternateLinks","link","meta","props","schemas","schema","safeJsonLdSerialize","JsonLd","data"],"mappings":"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","file":"chunk-T7EB7Y2S.cjs","sourcesContent":["import React from \"react\";\nimport type { SEOConfig } from \"../types/index.js\";\nimport {\n buildTitle,\n buildRobotsDirectives,\n buildOpenGraph,\n buildTwitterMetadata,\n buildAlternateLinks,\n} from \"../core/index.js\";\nimport { safeJsonLdSerialize } from \"../utils/index.js\";\n\nexport interface SEOHeadProps extends SEOConfig {\n /**\n * Optional nonce for CSP-compatible script tags.\n */\n nonce?: string;\n}\n\n/**\n * Generic SSR-safe React component that renders SEO-related tags.\n *\n * Renders: title, meta description, canonical link, robots meta,\n * Open Graph tags, Twitter tags, alternate/hreflang links,\n * additional meta/link tags, and JSON-LD scripts.\n *\n * Designed to be placed inside a <head> element in SSR apps.\n * Does NOT use any browser globals — fully SSR-compatible.\n */\nexport function SEOHead({\n title,\n titleTemplate,\n description,\n canonical,\n robots,\n openGraph,\n twitter,\n alternates,\n additionalMetaTags,\n additionalLinkTags,\n jsonLd,\n nonce,\n}: SEOHeadProps): React.ReactElement {\n const elements: React.ReactElement[] = [];\n let key = 0;\n const k = () => `seo-${key++}`;\n\n // Title\n const resolvedTitle = buildTitle(title, titleTemplate);\n if (resolvedTitle) {\n elements.push(React.createElement(\"title\", { key: k() }, resolvedTitle));\n }\n\n // Description\n if (description?.trim()) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n name: \"description\",\n content: description.trim(),\n })\n );\n }\n\n // Canonical\n if (canonical?.trim()) {\n elements.push(\n React.createElement(\"link\", {\n key: k(),\n rel: \"canonical\",\n href: canonical.trim(),\n })\n );\n }\n\n // Robots\n const robotsContent = buildRobotsDirectives(robots);\n if (robotsContent) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n name: \"robots\",\n content: robotsContent,\n })\n );\n }\n\n // Open Graph\n const ogTags = buildOpenGraph(openGraph);\n for (const tag of ogTags) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n property: tag.property,\n content: tag.content,\n })\n );\n }\n\n // Twitter\n const twitterTags = buildTwitterMetadata(twitter);\n for (const tag of twitterTags) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n name: tag.name,\n content: tag.content,\n })\n );\n }\n\n // Hreflang alternates\n const altLinks = buildAlternateLinks(alternates);\n for (const link of altLinks) {\n elements.push(\n React.createElement(\"link\", {\n key: k(),\n rel: link.rel,\n hrefLang: link.hreflang,\n href: link.href,\n })\n );\n }\n\n // Additional meta tags\n if (additionalMetaTags) {\n for (const meta of additionalMetaTags) {\n const props: Record<string, string> = { content: meta.content };\n if (meta.name) props.name = meta.name;\n if (meta.property) props.property = meta.property;\n elements.push(React.createElement(\"meta\", { key: k(), ...props }));\n }\n }\n\n // Additional link tags\n if (additionalLinkTags) {\n for (const link of additionalLinkTags) {\n elements.push(React.createElement(\"link\", { key: k(), ...link }));\n }\n }\n\n // JSON-LD\n if (jsonLd) {\n const schemas = Array.isArray(jsonLd) ? jsonLd : [jsonLd];\n for (const schema of schemas) {\n elements.push(\n React.createElement(\"script\", {\n key: k(),\n type: \"application/ld+json\",\n nonce,\n dangerouslySetInnerHTML: {\n __html: safeJsonLdSerialize(schema),\n },\n })\n );\n }\n }\n\n return React.createElement(React.Fragment, null, ...elements);\n}\n","import React from \"react\";\nimport { safeJsonLdSerialize } from \"../utils/index.js\";\n\nexport interface JsonLdProps {\n data: Record<string, unknown> | Array<Record<string, unknown>>;\n nonce?: string;\n}\n\n/**\n * Renders a <script type=\"application/ld+json\"> tag with safely serialized JSON-LD.\n * SSR-safe: no browser globals used.\n */\nexport function JsonLd({ data, nonce }: JsonLdProps): React.ReactElement {\n return React.createElement(\"script\", {\n type: \"application/ld+json\",\n nonce,\n dangerouslySetInnerHTML: {\n __html: safeJsonLdSerialize(data),\n },\n });\n}\n"]}
@@ -1,136 +0,0 @@
1
- type OpenGraphType = "website" | "article" | "product" | "profile" | "book" | "music.song" | "music.album" | "video.movie" | "video.episode" | (string & {});
2
- interface OpenGraphImage {
3
- url: string;
4
- alt?: string;
5
- width?: number;
6
- height?: number;
7
- type?: string;
8
- }
9
- interface OpenGraphConfig {
10
- title?: string;
11
- description?: string;
12
- url?: string;
13
- siteName?: string;
14
- type?: OpenGraphType;
15
- locale?: string;
16
- images?: OpenGraphImage[];
17
- }
18
- type TwitterCardType = "summary" | "summary_large_image" | "app" | "player";
19
- interface TwitterConfig {
20
- card?: TwitterCardType;
21
- site?: string;
22
- creator?: string;
23
- title?: string;
24
- description?: string;
25
- image?: string;
26
- imageAlt?: string;
27
- }
28
- interface RobotsConfig {
29
- index?: boolean;
30
- follow?: boolean;
31
- noarchive?: boolean;
32
- nosnippet?: boolean;
33
- noimageindex?: boolean;
34
- notranslate?: boolean;
35
- maxSnippet?: number;
36
- maxImagePreview?: "none" | "standard" | "large";
37
- maxVideoPreview?: number;
38
- }
39
- interface AlternateLink {
40
- hreflang: string;
41
- href: string;
42
- }
43
- interface SEOConfig {
44
- title?: string;
45
- titleTemplate?: string;
46
- description?: string;
47
- canonical?: string;
48
- robots?: RobotsConfig;
49
- openGraph?: OpenGraphConfig;
50
- twitter?: TwitterConfig;
51
- alternates?: AlternateLink[];
52
- additionalMetaTags?: Array<{
53
- name?: string;
54
- property?: string;
55
- content: string;
56
- }>;
57
- additionalLinkTags?: Array<{
58
- rel: string;
59
- href: string;
60
- hreflang?: string;
61
- type?: string;
62
- sizes?: string;
63
- }>;
64
- jsonLd?: Record<string, unknown> | Array<Record<string, unknown>>;
65
- }
66
- interface JSONLDBase {
67
- "@context"?: string;
68
- "@type": string;
69
- [key: string]: unknown;
70
- }
71
- interface BreadcrumbItem {
72
- name: string;
73
- url: string;
74
- }
75
- interface OrganizationSchemaInput {
76
- name: string;
77
- url: string;
78
- logo?: string;
79
- description?: string;
80
- sameAs?: string[];
81
- contactPoint?: {
82
- telephone?: string;
83
- contactType?: string;
84
- email?: string;
85
- areaServed?: string | string[];
86
- availableLanguage?: string | string[];
87
- };
88
- }
89
- interface WebsiteSchemaInput {
90
- name: string;
91
- url: string;
92
- description?: string;
93
- searchUrl?: string;
94
- searchQueryParam?: string;
95
- }
96
- interface ArticleSchemaInput {
97
- headline: string;
98
- url: string;
99
- description?: string;
100
- images?: string[];
101
- datePublished?: string;
102
- dateModified?: string;
103
- author?: {
104
- name: string;
105
- url?: string;
106
- } | Array<{
107
- name: string;
108
- url?: string;
109
- }>;
110
- publisher?: {
111
- name: string;
112
- logo?: string;
113
- };
114
- section?: string;
115
- keywords?: string[];
116
- }
117
- interface ProductSchemaInput {
118
- name: string;
119
- url: string;
120
- description?: string;
121
- images?: string[];
122
- brand?: string;
123
- sku?: string;
124
- gtin?: string;
125
- price?: number | string;
126
- priceCurrency?: string;
127
- availability?: "InStock" | "OutOfStock" | "PreOrder" | "Discontinued" | (string & {});
128
- ratingValue?: number;
129
- reviewCount?: number;
130
- }
131
- interface FAQItem {
132
- question: string;
133
- answer: string;
134
- }
135
-
136
- export type { ArticleSchemaInput as A, BreadcrumbItem as B, FAQItem as F, JSONLDBase as J, OrganizationSchemaInput as O, ProductSchemaInput as P, RobotsConfig as R, SEOConfig as S, TwitterConfig as T, WebsiteSchemaInput as W, AlternateLink as a, OpenGraphConfig as b, OpenGraphImage as c, OpenGraphType as d, TwitterCardType as e };
@@ -1,136 +0,0 @@
1
- type OpenGraphType = "website" | "article" | "product" | "profile" | "book" | "music.song" | "music.album" | "video.movie" | "video.episode" | (string & {});
2
- interface OpenGraphImage {
3
- url: string;
4
- alt?: string;
5
- width?: number;
6
- height?: number;
7
- type?: string;
8
- }
9
- interface OpenGraphConfig {
10
- title?: string;
11
- description?: string;
12
- url?: string;
13
- siteName?: string;
14
- type?: OpenGraphType;
15
- locale?: string;
16
- images?: OpenGraphImage[];
17
- }
18
- type TwitterCardType = "summary" | "summary_large_image" | "app" | "player";
19
- interface TwitterConfig {
20
- card?: TwitterCardType;
21
- site?: string;
22
- creator?: string;
23
- title?: string;
24
- description?: string;
25
- image?: string;
26
- imageAlt?: string;
27
- }
28
- interface RobotsConfig {
29
- index?: boolean;
30
- follow?: boolean;
31
- noarchive?: boolean;
32
- nosnippet?: boolean;
33
- noimageindex?: boolean;
34
- notranslate?: boolean;
35
- maxSnippet?: number;
36
- maxImagePreview?: "none" | "standard" | "large";
37
- maxVideoPreview?: number;
38
- }
39
- interface AlternateLink {
40
- hreflang: string;
41
- href: string;
42
- }
43
- interface SEOConfig {
44
- title?: string;
45
- titleTemplate?: string;
46
- description?: string;
47
- canonical?: string;
48
- robots?: RobotsConfig;
49
- openGraph?: OpenGraphConfig;
50
- twitter?: TwitterConfig;
51
- alternates?: AlternateLink[];
52
- additionalMetaTags?: Array<{
53
- name?: string;
54
- property?: string;
55
- content: string;
56
- }>;
57
- additionalLinkTags?: Array<{
58
- rel: string;
59
- href: string;
60
- hreflang?: string;
61
- type?: string;
62
- sizes?: string;
63
- }>;
64
- jsonLd?: Record<string, unknown> | Array<Record<string, unknown>>;
65
- }
66
- interface JSONLDBase {
67
- "@context"?: string;
68
- "@type": string;
69
- [key: string]: unknown;
70
- }
71
- interface BreadcrumbItem {
72
- name: string;
73
- url: string;
74
- }
75
- interface OrganizationSchemaInput {
76
- name: string;
77
- url: string;
78
- logo?: string;
79
- description?: string;
80
- sameAs?: string[];
81
- contactPoint?: {
82
- telephone?: string;
83
- contactType?: string;
84
- email?: string;
85
- areaServed?: string | string[];
86
- availableLanguage?: string | string[];
87
- };
88
- }
89
- interface WebsiteSchemaInput {
90
- name: string;
91
- url: string;
92
- description?: string;
93
- searchUrl?: string;
94
- searchQueryParam?: string;
95
- }
96
- interface ArticleSchemaInput {
97
- headline: string;
98
- url: string;
99
- description?: string;
100
- images?: string[];
101
- datePublished?: string;
102
- dateModified?: string;
103
- author?: {
104
- name: string;
105
- url?: string;
106
- } | Array<{
107
- name: string;
108
- url?: string;
109
- }>;
110
- publisher?: {
111
- name: string;
112
- logo?: string;
113
- };
114
- section?: string;
115
- keywords?: string[];
116
- }
117
- interface ProductSchemaInput {
118
- name: string;
119
- url: string;
120
- description?: string;
121
- images?: string[];
122
- brand?: string;
123
- sku?: string;
124
- gtin?: string;
125
- price?: number | string;
126
- priceCurrency?: string;
127
- availability?: "InStock" | "OutOfStock" | "PreOrder" | "Discontinued" | (string & {});
128
- ratingValue?: number;
129
- reviewCount?: number;
130
- }
131
- interface FAQItem {
132
- question: string;
133
- answer: string;
134
- }
135
-
136
- export type { ArticleSchemaInput as A, BreadcrumbItem as B, FAQItem as F, JSONLDBase as J, OrganizationSchemaInput as O, ProductSchemaInput as P, RobotsConfig as R, SEOConfig as S, TwitterConfig as T, WebsiteSchemaInput as W, AlternateLink as a, OpenGraphConfig as b, OpenGraphImage as c, OpenGraphType as d, TwitterCardType as e };