react-client-seo 1.0.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,6 +11,7 @@ A lightweight, production-ready client-side SEO renderer for React and Vite appl
11
11
  - ✅ **Component & Hook APIs** - Use `<Seo />` component or `useSeo()` hook
12
12
  - ✅ **Auto-updates** - Automatically creates/updates tags, avoids duplicates
13
13
  - ✅ **Comprehensive** - Supports title, meta tags, Open Graph, Twitter Cards, JSON-LD, and custom meta tags
14
+ - ✅ **Script Injection** - Built-in support for Google Analytics, Tag Manager, and custom scripts
14
15
 
15
16
  ## Installation
16
17
 
@@ -105,6 +106,90 @@ function MyComponent() {
105
106
  />
106
107
  ```
107
108
 
109
+ ### Google Analytics
110
+
111
+ ```tsx
112
+ <Seo
113
+ title="My Page"
114
+ description="Page description"
115
+ googleAnalyticsId="G-XXXXXXXXXX"
116
+ />
117
+ ```
118
+
119
+ **Note:** You only need to provide the ID - the package automatically injects both the async gtag.js script and the configuration script. Works with:
120
+
121
+ - Google Analytics 4 (GA4): `G-XXXXXXXXXX`
122
+ - Google Ads Conversion Tracking: `AW-XXXXXXXXXX`
123
+
124
+ Example with Google Ads conversion tracking:
125
+
126
+ ```tsx
127
+ <Seo
128
+ title="My Page"
129
+ description="Page description"
130
+ googleAnalyticsId="AW-XXXXXXXXXX"
131
+ />
132
+ ```
133
+
134
+ The package will automatically inject:
135
+
136
+ - `<script async src="https://www.googletagmanager.com/gtag/js?id=AW-XXXXXXXXXX"></script>`
137
+ - The inline configuration script with dataLayer initialization
138
+
139
+ ### Google Tag Manager
140
+
141
+ ```tsx
142
+ <Seo
143
+ title="My Page"
144
+ description="Page description"
145
+ googleTagManagerId="GTM-XXXXXXX"
146
+ />
147
+ ```
148
+
149
+ ### Custom Scripts
150
+
151
+ ```tsx
152
+ // External script
153
+ <Seo
154
+ title="My Page"
155
+ customScripts={[
156
+ {
157
+ src: "https://example.com/script.js",
158
+ id: "my-script",
159
+ async: true,
160
+ },
161
+ ]}
162
+ />
163
+
164
+ // Inline script
165
+ <Seo
166
+ title="My Page"
167
+ customScripts={[
168
+ {
169
+ content: "console.log('Hello from inline script');",
170
+ id: "inline-script",
171
+ },
172
+ ]}
173
+ />
174
+
175
+ // Multiple scripts with different strategies
176
+ <Seo
177
+ title="My Page"
178
+ customScripts={[
179
+ {
180
+ src: "https://example.com/async-script.js",
181
+ id: "async-script",
182
+ strategy: "async",
183
+ },
184
+ {
185
+ src: "https://example.com/defer-script.js",
186
+ id: "defer-script",
187
+ strategy: "defer",
188
+ },
189
+ ]}
190
+ />
191
+ ```
192
+
108
193
  ### Open Graph Tags
109
194
 
110
195
  ```tsx
@@ -275,6 +360,9 @@ function ProductPage({ product }) {
275
360
  | `customMeta` | `CustomMeta[]` | Custom meta tags |
276
361
  | `openGraph` | `OpenGraphMeta` | Additional Open Graph properties |
277
362
  | `twitter` | `TwitterCardMeta` | Additional Twitter Card properties |
363
+ | `googleAnalyticsId` | `string` | Google Analytics ID (gtag.js) |
364
+ | `googleTagManagerId` | `string` | Google Tag Manager ID |
365
+ | `customScripts` | `CustomScript[]` | Custom scripts to inject (external or inline) |
278
366
 
279
367
  ### `useSeo()` Hook
280
368
 
@@ -293,6 +381,7 @@ import type {
293
381
  OpenGraphMeta,
294
382
  TwitterCardMeta,
295
383
  CustomMeta,
384
+ CustomScript,
296
385
  JsonLd,
297
386
  } from "react-client-seo";
298
387
  ```
@@ -307,7 +396,9 @@ import type {
307
396
 
308
397
  ## Author
309
398
 
310
- **Rainard Joseph**
399
+ **Rainard Joseph**,
400
+ I'm working as a Software Project Manager at [Odidor](https://odidor.app/), working on the ERP and IMS software products. I love coding.
401
+ Connect with on [LinkedIn](https://www.linkedin.com/in/rainard-joseph).
311
402
 
312
403
  ## License
313
404
 
package/dist/Seo.d.ts CHANGED
@@ -18,5 +18,5 @@ import { SeoProps } from './types';
18
18
  * />
19
19
  * ```
20
20
  */
21
- export declare function Seo({ title, description, keywords, author, robots, language, viewport, generator, revisitAfter, rating, distribution, copyright, themeColor, referrer, formatDetection, mobileWebAppCapable, appleMobileWebAppCapable, geoRegion, geoPlacename, geoPosition, icbm, canonical, ogImage, ogType, ogUrl, ogTitle, ogDescription, ogSiteName, ogLocale, twitterCard, twitterSite, twitterCreator, twitterTitle, twitterDescription, twitterImage, twitterImageAlt, jsonLd, customMeta, openGraph, twitter, }: SeoProps): null;
21
+ export declare function Seo({ title, description, keywords, author, robots, language, viewport, generator, revisitAfter, rating, distribution, copyright, themeColor, referrer, formatDetection, mobileWebAppCapable, appleMobileWebAppCapable, geoRegion, geoPlacename, geoPosition, icbm, canonical, ogImage, ogType, ogUrl, ogTitle, ogDescription, ogSiteName, ogLocale, twitterCard, twitterSite, twitterCreator, twitterTitle, twitterDescription, twitterImage, twitterImageAlt, jsonLd, customMeta, openGraph, twitter, googleAnalyticsId, googleTagManagerId, customScripts, }: SeoProps): null;
22
22
  //# sourceMappingURL=Seo.d.ts.map
package/dist/Seo.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Seo.d.ts","sourceRoot":"","sources":["../src/Seo.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAcxC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,GAAG,CAAC,EAClB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,SAAS,EACT,UAAU,EACV,QAAQ,EACR,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,IAAI,EACJ,SAAS,EACT,OAAO,EACP,MAAM,EACN,KAAK,EACL,OAAO,EACP,aAAa,EACb,UAAU,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,MAAM,EACN,UAAU,EACV,SAAS,EACT,OAAO,GACR,EAAE,QAAQ,QAuOV"}
1
+ {"version":3,"file":"Seo.d.ts","sourceRoot":"","sources":["../src/Seo.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAiBxC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,GAAG,CAAC,EAClB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,SAAS,EACT,UAAU,EACV,QAAQ,EACR,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,IAAI,EACJ,SAAS,EACT,OAAO,EACP,MAAM,EACN,KAAK,EACL,OAAO,EACP,aAAa,EACb,UAAU,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,MAAM,EACN,UAAU,EACV,SAAS,EACT,OAAO,EACP,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,GACd,EAAE,QAAQ,QAsQV"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,13 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Y=require("react");function X(e,t){const n=`meta[${e}="${t}"]`;let r=document.querySelector(n);return r||(r=document.createElement("meta"),r.setAttribute(e,t),document.head.appendChild(r)),r}function i(e,t){if(!t)return;X("name",e).setAttribute("content",t)}function a(e,t){if(t==null||t==="")return;X("property",e).setAttribute("content",String(t))}function R(e){e&&(document.title=e)}function U(e){if(!e)return;let t=document.querySelector('link[rel="canonical"]');t||(t=document.createElement("link"),t.setAttribute("rel","canonical"),document.head.appendChild(t)),t.setAttribute("href",e)}function re(){const e=document.querySelector('link[rel="canonical"]');e&&e.remove()}function k(e){e&&(e.title&&a("og:title",e.title),e.description&&a("og:description",e.description),e.type&&a("og:type",e.type),e.url&&a("og:url",e.url),e.image&&a("og:image",e.image),e.imageWidth&&a("og:image:width",e.imageWidth),e.imageHeight&&a("og:image:height",e.imageHeight),e.imageAlt&&a("og:image:alt",e.imageAlt),e.siteName&&a("og:site_name",e.siteName),e.locale&&a("og:locale",e.locale),Object.keys(e).forEach(t=>{if(t.startsWith("og:")&&t!=="og:title"&&t!=="og:description"&&t!=="og:type"&&t!=="og:url"&&t!=="og:image"&&t!=="og:imageWidth"&&t!=="og:imageHeight"&&t!=="og:imageAlt"&&t!=="og:siteName"&&t!=="og:locale"){const n=e[t];n!=null&&n!==""&&a(t,n)}}))}function ee(e){e&&(e.card&&i("twitter:card",e.card),e.site&&i("twitter:site",e.site),e.creator&&i("twitter:creator",e.creator),e.title&&i("twitter:title",e.title),e.description&&i("twitter:description",e.description),e.image&&i("twitter:image",e.image),e.imageAlt&&i("twitter:image:alt",e.imageAlt),Object.keys(e).forEach(t=>{if(t.startsWith("twitter:")&&t!=="twitter:card"&&t!=="twitter:site"&&t!=="twitter:creator"&&t!=="twitter:title"&&t!=="twitter:description"&&t!=="twitter:image"&&t!=="twitter:imageAlt"){const n=e[t];n!=null&&n!==""&&i(t,String(n))}}))}function te(e){!e||!Array.isArray(e)||e.forEach(t=>{if(!t.content)return;let n=null;if(t.name)n=X("name",t.name);else if(t.property)n=X("property",t.property);else if(t.httpEquiv){const r=`meta[http-equiv="${t.httpEquiv}"]`;n=document.querySelector(r),n||(n=document.createElement("meta"),n.setAttribute("http-equiv",t.httpEquiv),document.head.appendChild(n))}else if(t.charset){let r=document.querySelector("meta[charset]");r||(r=document.createElement("meta"),r.setAttribute("charset",t.charset),document.head.insertBefore(r,document.head.firstChild));return}n&&n.setAttribute("content",t.content)})}function ie(e,t){const n=document.createElement("script");n.type="application/ld+json";{n.id=t;const r=document.getElementById(t);r&&r.remove()}return n.textContent=JSON.stringify(e),document.head.appendChild(n),()=>{n.remove()}}function fe(e){const t=document.getElementById(e);t&&t.getAttribute("type")==="application/ld+json"&&t.remove()}function ne(e){return e?Array.isArray(e)?e.join(", "):e:""}const oe="react-client-seo-jsonld";function ae({title:e,description:t,keywords:n,author:r,robots:c,language:h,viewport:b,generator:v,revisitAfter:g,rating:S,distribution:A,copyright:E,themeColor:y,referrer:j,formatDetection:O,mobileWebAppCapable:q,appleMobileWebAppCapable:C,geoRegion:N,geoPlacename:J,geoPosition:B,icbm:D,canonical:u,ogImage:m,ogType:T,ogUrl:d,ogTitle:p,ogDescription:_,ogSiteName:$,ogLocale:w,twitterCard:H,twitterSite:L,twitterCreator:M,twitterTitle:W,twitterDescription:x,twitterImage:G,twitterImageAlt:I,jsonLd:K,customMeta:z,openGraph:P,twitter:Q}){return Y.useEffect(()=>{e&&R(e),t&&i("description",t);const V=ne(n);V&&i("keywords",V),r&&i("author",r),c&&i("robots",c),h&&(i("language",h),i("content-language",h)),b&&i("viewport",b),v&&i("generator",v),g&&i("revisit-after",g),S&&i("rating",S),A&&i("distribution",A),E&&i("copyright",E),y&&i("theme-color",y),j&&i("referrer",j),O&&i("format-detection",O),q&&i("mobile-web-app-capable",q),C&&i("apple-mobile-web-app-capable",C),N&&i("geo.region",N),J&&i("geo.placename",J),B&&i("geo.position",B),D&&i("ICBM",D),u&&U(u);const f={...P};(p||e)&&(f.title=p||e),(_||t)&&(f.description=_||t),T&&(f.type=T),(d||u)&&(f.url=d||u),m&&(f.image=m),$&&(f.siteName=$),w&&(f.locale=w),Object.keys(f).length>0&&k(f);const o={...Q};H&&(o.card=H),L&&(o.site=L),M&&(o.creator=M),(W||e)&&(o.title=W||e),(x||t)&&(o.description=x||t),(G||m)&&(o.image=G||m),I&&(o.imageAlt=I),Object.keys(o).length>0&&ee(o),z&&te(z);let F=null;return K&&(F=ie(K,oe)),()=>{F&&F()}},[e,t,n,r,c,h,b,v,g,S,A,E,y,j,O,q,C,N,J,B,D,u,m,T,d,p,_,$,w,H,L,M,W,x,G,I,K,z,P,Q]),null}const Z="react-client-seo-jsonld";function ce(){const e=Y.useCallback(n=>{const{title:r,description:c,keywords:h,author:b,robots:v,language:g,viewport:S,generator:A,revisitAfter:E,rating:y,distribution:j,copyright:O,themeColor:q,referrer:C,formatDetection:N,mobileWebAppCapable:J,appleMobileWebAppCapable:B,geoRegion:D,geoPlacename:u,geoPosition:m,icbm:T,canonical:d,ogImage:p,ogType:_,ogUrl:$,ogTitle:w,ogDescription:H,ogSiteName:L,ogLocale:M,twitterCard:W,twitterSite:x,twitterCreator:G,twitterTitle:I,twitterDescription:K,twitterImage:z,twitterImageAlt:P,jsonLd:Q,customMeta:V,openGraph:f,twitter:o}=n;r&&R(r),c&&i("description",c);const F=ne(h);F&&i("keywords",F),b&&i("author",b),v&&i("robots",v),g&&(i("language",g),i("content-language",g)),S&&i("viewport",S),A&&i("generator",A),E&&i("revisit-after",E),y&&i("rating",y),j&&i("distribution",j),O&&i("copyright",O),q&&i("theme-color",q),C&&i("referrer",C),N&&i("format-detection",N),J&&i("mobile-web-app-capable",J),B&&i("apple-mobile-web-app-capable",B),D&&i("geo.region",D),u&&i("geo.placename",u),m&&i("geo.position",m),T&&i("ICBM",T),d&&U(d);const l={...f};(w||r)&&(l.title=w||r),(H||c)&&(l.description=H||c),_&&(l.type=_),($||d)&&(l.url=$||d),p&&(l.image=p),L&&(l.siteName=L),M&&(l.locale=M),Object.keys(l).length>0&&k(l);const s={...o};W&&(s.card=W),x&&(s.site=x),G&&(s.creator=G),(I||r)&&(s.title=I||r),(K||c)&&(s.description=K||c),(z||p)&&(s.image=z||p),P&&(s.imageAlt=P),Object.keys(s).length>0&&ee(s),V&&te(V),Q&&ie(Q,Z)},[]),t=Y.useCallback(()=>{re(),fe(Z)},[]);return{updateSeo:e,clearSeo:t}}exports.Seo=ae;exports.useSeo=ce;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const te=require("react");function k(e,t){const i=`meta[${e}="${t}"]`;let r=document.querySelector(i);return r||(r=document.createElement("meta"),r.setAttribute(e,t),document.head.appendChild(r)),r}function n(e,t){if(!t)return;k("name",e).setAttribute("content",t)}function l(e,t){if(t==null||t==="")return;k("property",e).setAttribute("content",String(t))}function ne(e){e&&(document.title=e)}function re(e){if(!e)return;let t=document.querySelector('link[rel="canonical"]');t||(t=document.createElement("link"),t.setAttribute("rel","canonical"),document.head.appendChild(t)),t.setAttribute("href",e)}function pe(){const e=document.querySelector('link[rel="canonical"]');e&&e.remove()}function ae(e){e&&(e.title&&l("og:title",e.title),e.description&&l("og:description",e.description),e.type&&l("og:type",e.type),e.url&&l("og:url",e.url),e.image&&l("og:image",e.image),e.imageWidth&&l("og:image:width",e.imageWidth),e.imageHeight&&l("og:image:height",e.imageHeight),e.imageAlt&&l("og:image:alt",e.imageAlt),e.siteName&&l("og:site_name",e.siteName),e.locale&&l("og:locale",e.locale),Object.keys(e).forEach(t=>{if(t.startsWith("og:")&&t!=="og:title"&&t!=="og:description"&&t!=="og:type"&&t!=="og:url"&&t!=="og:image"&&t!=="og:imageWidth"&&t!=="og:imageHeight"&&t!=="og:imageAlt"&&t!=="og:siteName"&&t!=="og:locale"){const i=e[t];i!=null&&i!==""&&l(t,i)}}))}function ce(e){e&&(e.card&&n("twitter:card",e.card),e.site&&n("twitter:site",e.site),e.creator&&n("twitter:creator",e.creator),e.title&&n("twitter:title",e.title),e.description&&n("twitter:description",e.description),e.image&&n("twitter:image",e.image),e.imageAlt&&n("twitter:image:alt",e.imageAlt),Object.keys(e).forEach(t=>{if(t.startsWith("twitter:")&&t!=="twitter:card"&&t!=="twitter:site"&&t!=="twitter:creator"&&t!=="twitter:title"&&t!=="twitter:description"&&t!=="twitter:image"&&t!=="twitter:imageAlt"){const i=e[t];i!=null&&i!==""&&n(t,String(i))}}))}function oe(e){!e||!Array.isArray(e)||e.forEach(t=>{if(!t.content)return;let i=null;if(t.name)i=k("name",t.name);else if(t.property)i=k("property",t.property);else if(t.httpEquiv){const r=`meta[http-equiv="${t.httpEquiv}"]`;i=document.querySelector(r),i||(i=document.createElement("meta"),i.setAttribute("http-equiv",t.httpEquiv),document.head.appendChild(i))}else if(t.charset){let r=document.querySelector("meta[charset]");r||(r=document.createElement("meta"),r.setAttribute("charset",t.charset),document.head.insertBefore(r,document.head.firstChild));return}i&&i.setAttribute("content",t.content)})}function fe(e,t){const i=document.createElement("script");i.type="application/ld+json";{i.id=t;const r=document.getElementById(t);r&&r.remove()}return i.textContent=JSON.stringify(e),document.head.appendChild(i),()=>{i.remove()}}function ge(e){const t=document.getElementById(e);t&&t.getAttribute("type")==="application/ld+json"&&t.remove()}function se(e){return e?Array.isArray(e)?e.join(", "):e:""}function y(e){const t=document.getElementById(e);t&&t.tagName==="SCRIPT"&&t.remove()}function le(e){const t="react-client-seo-ga",i="react-client-seo-ga-config";y(t),y(i);const r=document.createElement("script");r.id=t,r.async=!0,r.src=`https://www.googletagmanager.com/gtag/js?id=${e}`,document.head.appendChild(r);const a=document.createElement("script");return a.id=i,a.textContent=`
2
+ window.dataLayer = window.dataLayer || [];
3
+ function gtag(){dataLayer.push(arguments);}
4
+ gtag('js', new Date());
5
+ gtag('config', '${e}');
6
+ `,document.head.appendChild(a),()=>{y(t),y(i)}}function ue(e){const t="react-client-seo-gtm",i="react-client-seo-gtm-noscript";y(t);const r=document.getElementById(i);r&&r.remove();const a=document.createElement("script");a.id=t,a.textContent=`
7
+ (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
8
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
9
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
10
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
11
+ })(window,document,'script','dataLayer','${e}');
12
+ `,document.head.appendChild(a);const u=document.createElement("noscript");return u.id=i,u.innerHTML=`<iframe src="https://www.googletagmanager.com/ns.html?id=${e}" height="0" width="0" style="display:none;visibility:hidden"></iframe>`,document.head.appendChild(u),()=>{y(t);const d=document.getElementById(i);d&&d.remove()}}function de(e){if(!e.src&&!e.content)return console.warn("CustomScript must have either src or content"),()=>{};const t=e.id||`react-client-seo-custom-${Date.now()}`;e.id&&y(e.id);const i=document.createElement("script");return i.id=t,e.src&&(i.src=e.src),e.content&&(i.textContent=e.content),e.type?i.type=e.type:i.type="text/javascript",(e.strategy==="async"||e.async)&&(i.async=!0),(e.strategy==="defer"||e.defer)&&(i.defer=!0),document.head.appendChild(i),()=>{y(t)}}const he="react-client-seo-jsonld";function ye({title:e,description:t,keywords:i,author:r,robots:a,language:u,viewport:d,generator:v,revisitAfter:E,rating:w,distribution:b,copyright:S,themeColor:j,referrer:A,formatDetection:T,mobileWebAppCapable:O,appleMobileWebAppCapable:N,geoRegion:_,geoPlacename:C,geoPosition:D,icbm:I,canonical:m,ogImage:p,ogType:q,ogUrl:g,ogTitle:h,ogDescription:B,ogSiteName:G,ogLocale:L,twitterCard:$,twitterSite:x,twitterCreator:M,twitterTitle:J,twitterDescription:H,twitterImage:P,twitterImageAlt:R,jsonLd:W,customMeta:F,openGraph:V,twitter:X,googleAnalyticsId:K,googleTagManagerId:Y,customScripts:z}){return te.useEffect(()=>{e&&ne(e),t&&n("description",t);const Z=se(i);Z&&n("keywords",Z),r&&n("author",r),a&&n("robots",a),u&&(n("language",u),n("content-language",u)),d&&n("viewport",d),v&&n("generator",v),E&&n("revisit-after",E),w&&n("rating",w),b&&n("distribution",b),S&&n("copyright",S),j&&n("theme-color",j),A&&n("referrer",A),T&&n("format-detection",T),O&&n("mobile-web-app-capable",O),N&&n("apple-mobile-web-app-capable",N),_&&n("geo.region",_),C&&n("geo.placename",C),D&&n("geo.position",D),I&&n("ICBM",I),m&&re(m);const s={...V};(h||e)&&(s.title=h||e),(B||t)&&(s.description=B||t),q&&(s.type=q),(g||m)&&(s.url=g||m),p&&(s.image=p),G&&(s.siteName=G),L&&(s.locale=L),Object.keys(s).length>0&&ae(s);const c={...X};$&&(c.card=$),x&&(c.site=x),M&&(c.creator=M),(J||e)&&(c.title=J||e),(H||t)&&(c.description=H||t),(P||p)&&(c.image=P||p),R&&(c.imageAlt=R),Object.keys(c).length>0&&ce(c),F&&oe(F);let Q=null;W&&(Q=fe(W,he));let o=null;K&&(o=le(K));let f=null;Y&&(f=ue(Y));const U=[];return z&&Array.isArray(z)&&z.forEach(ee=>{const me=de(ee);U.push(me)}),()=>{Q&&Q(),o&&o(),f&&f(),U.forEach(ee=>ee())}},[e,t,i,r,a,u,d,v,E,w,b,S,j,A,T,O,N,_,C,D,I,m,p,q,g,h,B,G,L,$,x,M,J,H,P,R,W,F,V,X,K,Y,z]),null}const ie="react-client-seo-jsonld";function Ee(){const e=te.useCallback(i=>{const{title:r,description:a,keywords:u,author:d,robots:v,language:E,viewport:w,generator:b,revisitAfter:S,rating:j,distribution:A,copyright:T,themeColor:O,referrer:N,formatDetection:_,mobileWebAppCapable:C,appleMobileWebAppCapable:D,geoRegion:I,geoPlacename:m,geoPosition:p,icbm:q,canonical:g,ogImage:h,ogType:B,ogUrl:G,ogTitle:L,ogDescription:$,ogSiteName:x,ogLocale:M,twitterCard:J,twitterSite:H,twitterCreator:P,twitterTitle:R,twitterDescription:W,twitterImage:F,twitterImageAlt:V,jsonLd:X,customMeta:K,openGraph:Y,twitter:z,googleAnalyticsId:Z,googleTagManagerId:s,customScripts:c}=i;r&&ne(r),a&&n("description",a);const Q=se(u);Q&&n("keywords",Q),d&&n("author",d),v&&n("robots",v),E&&(n("language",E),n("content-language",E)),w&&n("viewport",w),b&&n("generator",b),S&&n("revisit-after",S),j&&n("rating",j),A&&n("distribution",A),T&&n("copyright",T),O&&n("theme-color",O),N&&n("referrer",N),_&&n("format-detection",_),C&&n("mobile-web-app-capable",C),D&&n("apple-mobile-web-app-capable",D),I&&n("geo.region",I),m&&n("geo.placename",m),p&&n("geo.position",p),q&&n("ICBM",q),g&&re(g);const o={...Y};(L||r)&&(o.title=L||r),($||a)&&(o.description=$||a),B&&(o.type=B),(G||g)&&(o.url=G||g),h&&(o.image=h),x&&(o.siteName=x),M&&(o.locale=M),Object.keys(o).length>0&&ae(o);const f={...z};J&&(f.card=J),H&&(f.site=H),P&&(f.creator=P),(R||r)&&(f.title=R||r),(W||a)&&(f.description=W||a),(F||h)&&(f.image=F||h),V&&(f.imageAlt=V),Object.keys(f).length>0&&ce(f),K&&oe(K),X&&fe(X,ie),Z&&le(Z),s&&ue(s),c&&Array.isArray(c)&&c.forEach(U=>{de(U)})},[]),t=te.useCallback(()=>{pe(),ge(ie)},[]);return{updateSeo:e,clearSeo:t}}exports.Seo=ye;exports.useSeo=Ee;
2
13
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/utils.ts","../src/Seo.tsx","../src/useSeo.ts"],"sourcesContent":["import type { CustomMeta, JsonLd, OpenGraphMeta, TwitterCardMeta } from './types';\r\n\r\n/**\r\n * Get or create a meta tag element\r\n */\r\nfunction getOrCreateMetaTag(attribute: 'name' | 'property', value: string): HTMLMetaElement {\r\n const selector = `meta[${attribute}=\"${value}\"]`;\r\n let element = document.querySelector<HTMLMetaElement>(selector);\r\n\r\n if (!element) {\r\n element = document.createElement('meta');\r\n element.setAttribute(attribute, value);\r\n document.head.appendChild(element);\r\n }\r\n\r\n return element;\r\n}\r\n\r\n/**\r\n * Set a meta tag by name\r\n */\r\nexport function setMetaTag(name: string, content: string): void {\r\n if (!content) return;\r\n\r\n const element = getOrCreateMetaTag('name', name);\r\n element.setAttribute('content', content);\r\n}\r\n\r\n/**\r\n * Set a meta tag by property (for Open Graph)\r\n */\r\nexport function setMetaProperty(property: string, content: string | number): void {\r\n if (content === undefined || content === null || content === '') return;\r\n\r\n const element = getOrCreateMetaTag('property', property);\r\n element.setAttribute('content', String(content));\r\n}\r\n\r\n/**\r\n * Set the page title\r\n */\r\nexport function setTitle(title: string): void {\r\n if (!title) return;\r\n document.title = title;\r\n}\r\n\r\n/**\r\n * Set canonical URL\r\n */\r\nexport function setCanonical(url: string): void {\r\n if (!url) return;\r\n\r\n let link = document.querySelector<HTMLLinkElement>('link[rel=\"canonical\"]');\r\n if (!link) {\r\n link = document.createElement('link');\r\n link.setAttribute('rel', 'canonical');\r\n document.head.appendChild(link);\r\n }\r\n link.setAttribute('href', url);\r\n}\r\n\r\n/**\r\n * Remove canonical URL\r\n */\r\nexport function removeCanonical(): void {\r\n const link = document.querySelector<HTMLLinkElement>('link[rel=\"canonical\"]');\r\n if (link) {\r\n link.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Set Open Graph meta tags\r\n */\r\nexport function setOpenGraphTags(og: OpenGraphMeta): void {\r\n if (!og) return;\r\n\r\n // Standard Open Graph properties\r\n if (og.title) setMetaProperty('og:title', og.title);\r\n if (og.description) setMetaProperty('og:description', og.description);\r\n if (og.type) setMetaProperty('og:type', og.type);\r\n if (og.url) setMetaProperty('og:url', og.url);\r\n if (og.image) setMetaProperty('og:image', og.image);\r\n if (og.imageWidth) setMetaProperty('og:image:width', og.imageWidth);\r\n if (og.imageHeight) setMetaProperty('og:image:height', og.imageHeight);\r\n if (og.imageAlt) setMetaProperty('og:image:alt', og.imageAlt);\r\n if (og.siteName) setMetaProperty('og:site_name', og.siteName);\r\n if (og.locale) setMetaProperty('og:locale', og.locale);\r\n\r\n // Handle additional custom og:* properties\r\n Object.keys(og).forEach((key) => {\r\n if (key.startsWith('og:') && key !== 'og:title' && key !== 'og:description' && \r\n key !== 'og:type' && key !== 'og:url' && key !== 'og:image' && \r\n key !== 'og:imageWidth' && key !== 'og:imageHeight' && \r\n key !== 'og:imageAlt' && key !== 'og:siteName' && key !== 'og:locale') {\r\n const value = og[key as keyof OpenGraphMeta];\r\n if (value !== undefined && value !== null && value !== '') {\r\n setMetaProperty(key, value as string | number);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Set Twitter Card meta tags\r\n */\r\nexport function setTwitterCardTags(twitter: TwitterCardMeta): void {\r\n if (!twitter) return;\r\n\r\n if (twitter.card) setMetaTag('twitter:card', twitter.card);\r\n if (twitter.site) setMetaTag('twitter:site', twitter.site);\r\n if (twitter.creator) setMetaTag('twitter:creator', twitter.creator);\r\n if (twitter.title) setMetaTag('twitter:title', twitter.title);\r\n if (twitter.description) setMetaTag('twitter:description', twitter.description);\r\n if (twitter.image) setMetaTag('twitter:image', twitter.image);\r\n if (twitter.imageAlt) setMetaTag('twitter:image:alt', twitter.imageAlt);\r\n\r\n // Handle additional custom twitter:* properties\r\n Object.keys(twitter).forEach((key) => {\r\n if (key.startsWith('twitter:') && key !== 'twitter:card' && key !== 'twitter:site' && \r\n key !== 'twitter:creator' && key !== 'twitter:title' && \r\n key !== 'twitter:description' && key !== 'twitter:image' && \r\n key !== 'twitter:imageAlt') {\r\n const value = twitter[key as keyof TwitterCardMeta];\r\n if (value !== undefined && value !== null && value !== '') {\r\n setMetaTag(key, String(value));\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Set custom meta tags\r\n */\r\nexport function setCustomMetaTags(customMeta: CustomMeta[]): void {\r\n if (!customMeta || !Array.isArray(customMeta)) return;\r\n\r\n customMeta.forEach((meta) => {\r\n if (!meta.content) return;\r\n\r\n let element: HTMLMetaElement | null = null;\r\n\r\n if (meta.name) {\r\n element = getOrCreateMetaTag('name', meta.name);\r\n } else if (meta.property) {\r\n element = getOrCreateMetaTag('property', meta.property);\r\n } else if (meta.httpEquiv) {\r\n const selector = `meta[http-equiv=\"${meta.httpEquiv}\"]`;\r\n element = document.querySelector<HTMLMetaElement>(selector);\r\n if (!element) {\r\n element = document.createElement('meta');\r\n element.setAttribute('http-equiv', meta.httpEquiv);\r\n document.head.appendChild(element);\r\n }\r\n } else if (meta.charset) {\r\n let charsetElement = document.querySelector<HTMLMetaElement>('meta[charset]');\r\n if (!charsetElement) {\r\n charsetElement = document.createElement('meta');\r\n charsetElement.setAttribute('charset', meta.charset);\r\n document.head.insertBefore(charsetElement, document.head.firstChild);\r\n }\r\n return;\r\n }\r\n\r\n if (element) {\r\n element.setAttribute('content', meta.content);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Inject JSON-LD structured data\r\n */\r\nexport function injectJsonLd(data: JsonLd, id?: string): () => void {\r\n const script = document.createElement('script');\r\n script.type = 'application/ld+json';\r\n if (id) {\r\n script.id = id;\r\n // Remove existing script with same id\r\n const existing = document.getElementById(id);\r\n if (existing) {\r\n existing.remove();\r\n }\r\n }\r\n script.textContent = JSON.stringify(data);\r\n document.head.appendChild(script);\r\n\r\n // Return cleanup function\r\n return () => {\r\n script.remove();\r\n };\r\n}\r\n\r\n/**\r\n * Remove JSON-LD script by id\r\n */\r\nexport function removeJsonLd(id: string): void {\r\n const script = document.getElementById(id);\r\n if (script && script.getAttribute('type') === 'application/ld+json') {\r\n script.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Format keywords as string\r\n */\r\nexport function formatKeywords(keywords: string | string[] | undefined): string {\r\n if (!keywords) return '';\r\n if (Array.isArray(keywords)) {\r\n return keywords.join(', ');\r\n }\r\n return keywords;\r\n}\r\n\r\n","import { useEffect } from 'react';\r\nimport type { SeoProps } from './types';\r\nimport {\r\n setTitle,\r\n setMetaTag,\r\n setCanonical,\r\n setOpenGraphTags,\r\n setTwitterCardTags,\r\n setCustomMetaTags,\r\n injectJsonLd,\r\n formatKeywords,\r\n} from './utils';\r\n\r\nconst JSON_LD_ID = 'react-client-seo-jsonld';\r\n\r\n/**\r\n * SEO Component\r\n * \r\n * Renders and updates SEO meta tags in the document head.\r\n * Returns null (no UI rendering).\r\n * \r\n * @example\r\n * ```tsx\r\n * <Seo\r\n * title=\"My Page Title\"\r\n * description=\"Page description\"\r\n * keywords={['react', 'seo']}\r\n * canonical=\"https://example.com/page\"\r\n * ogImage=\"https://example.com/image.jpg\"\r\n * jsonLd={{ \"@context\": \"https://schema.org\", \"@type\": \"WebPage\" }}\r\n * />\r\n * ```\r\n */\r\nexport function Seo({\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n}: SeoProps) {\r\n useEffect(() => {\r\n // Set title\r\n if (title) {\r\n setTitle(title);\r\n }\r\n\r\n // Set description\r\n if (description) {\r\n setMetaTag('description', description);\r\n }\r\n\r\n // Set keywords\r\n const keywordsStr = formatKeywords(keywords);\r\n if (keywordsStr) {\r\n setMetaTag('keywords', keywordsStr);\r\n }\r\n\r\n // Set author\r\n if (author) {\r\n setMetaTag('author', author);\r\n }\r\n\r\n // Set robots\r\n if (robots) {\r\n setMetaTag('robots', robots);\r\n }\r\n\r\n // Set language\r\n if (language) {\r\n setMetaTag('language', language);\r\n setMetaTag('content-language', language);\r\n }\r\n\r\n // Set viewport\r\n if (viewport) {\r\n setMetaTag('viewport', viewport);\r\n }\r\n\r\n // Set generator\r\n if (generator) {\r\n setMetaTag('generator', generator);\r\n }\r\n\r\n // Set revisit-after\r\n if (revisitAfter) {\r\n setMetaTag('revisit-after', revisitAfter);\r\n }\r\n\r\n // Set rating\r\n if (rating) {\r\n setMetaTag('rating', rating);\r\n }\r\n\r\n // Set distribution\r\n if (distribution) {\r\n setMetaTag('distribution', distribution);\r\n }\r\n\r\n // Set copyright\r\n if (copyright) {\r\n setMetaTag('copyright', copyright);\r\n }\r\n\r\n // Set theme-color\r\n if (themeColor) {\r\n setMetaTag('theme-color', themeColor);\r\n }\r\n\r\n // Set referrer\r\n if (referrer) {\r\n setMetaTag('referrer', referrer);\r\n }\r\n\r\n // Set format-detection\r\n if (formatDetection) {\r\n setMetaTag('format-detection', formatDetection);\r\n }\r\n\r\n // Set mobile-web-app-capable\r\n if (mobileWebAppCapable) {\r\n setMetaTag('mobile-web-app-capable', mobileWebAppCapable);\r\n }\r\n\r\n // Set apple-mobile-web-app-capable\r\n if (appleMobileWebAppCapable) {\r\n setMetaTag('apple-mobile-web-app-capable', appleMobileWebAppCapable);\r\n }\r\n\r\n // Set geo tags\r\n if (geoRegion) {\r\n setMetaTag('geo.region', geoRegion);\r\n }\r\n if (geoPlacename) {\r\n setMetaTag('geo.placename', geoPlacename);\r\n }\r\n if (geoPosition) {\r\n setMetaTag('geo.position', geoPosition);\r\n }\r\n if (icbm) {\r\n setMetaTag('ICBM', icbm);\r\n }\r\n\r\n // Set canonical URL\r\n if (canonical) {\r\n setCanonical(canonical);\r\n }\r\n\r\n // Build Open Graph object\r\n const ogData: any = {\r\n ...openGraph,\r\n };\r\n\r\n if (ogTitle || title) {\r\n ogData.title = ogTitle || title;\r\n }\r\n if (ogDescription || description) {\r\n ogData.description = ogDescription || description;\r\n }\r\n if (ogType) {\r\n ogData.type = ogType;\r\n }\r\n if (ogUrl || canonical) {\r\n ogData.url = ogUrl || canonical;\r\n }\r\n if (ogImage) {\r\n ogData.image = ogImage;\r\n }\r\n if (ogSiteName) {\r\n ogData.siteName = ogSiteName;\r\n }\r\n if (ogLocale) {\r\n ogData.locale = ogLocale;\r\n }\r\n\r\n if (Object.keys(ogData).length > 0) {\r\n setOpenGraphTags(ogData);\r\n }\r\n\r\n // Build Twitter Card object\r\n const twitterData: any = {\r\n ...twitter,\r\n };\r\n\r\n if (twitterCard) {\r\n twitterData.card = twitterCard;\r\n }\r\n if (twitterSite) {\r\n twitterData.site = twitterSite;\r\n }\r\n if (twitterCreator) {\r\n twitterData.creator = twitterCreator;\r\n }\r\n if (twitterTitle || title) {\r\n twitterData.title = twitterTitle || title;\r\n }\r\n if (twitterDescription || description) {\r\n twitterData.description = twitterDescription || description;\r\n }\r\n if (twitterImage || ogImage) {\r\n twitterData.image = twitterImage || ogImage;\r\n }\r\n if (twitterImageAlt) {\r\n twitterData.imageAlt = twitterImageAlt;\r\n }\r\n\r\n if (Object.keys(twitterData).length > 0) {\r\n setTwitterCardTags(twitterData);\r\n }\r\n\r\n // Set custom meta tags\r\n if (customMeta) {\r\n setCustomMetaTags(customMeta);\r\n }\r\n\r\n // Inject JSON-LD\r\n let cleanupJsonLd: (() => void) | null = null;\r\n if (jsonLd) {\r\n cleanupJsonLd = injectJsonLd(jsonLd, JSON_LD_ID);\r\n }\r\n\r\n // Cleanup function\r\n return () => {\r\n if (cleanupJsonLd) {\r\n cleanupJsonLd();\r\n }\r\n };\r\n }, [\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n ]);\r\n\r\n return null;\r\n}\r\n\r\n","import { useCallback } from 'react';\r\nimport type { SeoProps, UseSeoReturn } from './types';\r\nimport {\r\n setTitle,\r\n setMetaTag,\r\n setCanonical,\r\n setOpenGraphTags,\r\n setTwitterCardTags,\r\n setCustomMetaTags,\r\n injectJsonLd,\r\n formatKeywords,\r\n removeCanonical,\r\n removeJsonLd,\r\n} from './utils';\r\n\r\nconst JSON_LD_ID = 'react-client-seo-jsonld';\r\n\r\n/**\r\n * useSeo Hook\r\n * \r\n * Hook-based API for managing SEO meta tags.\r\n * \r\n * @example\r\n * ```tsx\r\n * function MyComponent() {\r\n * const { updateSeo } = useSeo();\r\n * \r\n * useEffect(() => {\r\n * updateSeo({\r\n * title: 'My Page',\r\n * description: 'Page description',\r\n * });\r\n * }, []);\r\n * \r\n * return <div>Content</div>;\r\n * }\r\n * ```\r\n */\r\nexport function useSeo(): UseSeoReturn {\r\n const updateSeo = useCallback((props: SeoProps) => {\r\n const {\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n } = props;\r\n\r\n // Set title\r\n if (title) {\r\n setTitle(title);\r\n }\r\n\r\n // Set description\r\n if (description) {\r\n setMetaTag('description', description);\r\n }\r\n\r\n // Set keywords\r\n const keywordsStr = formatKeywords(keywords);\r\n if (keywordsStr) {\r\n setMetaTag('keywords', keywordsStr);\r\n }\r\n\r\n // Set author\r\n if (author) {\r\n setMetaTag('author', author);\r\n }\r\n\r\n // Set robots\r\n if (robots) {\r\n setMetaTag('robots', robots);\r\n }\r\n\r\n // Set language\r\n if (language) {\r\n setMetaTag('language', language);\r\n setMetaTag('content-language', language);\r\n }\r\n\r\n // Set viewport\r\n if (viewport) {\r\n setMetaTag('viewport', viewport);\r\n }\r\n\r\n // Set generator\r\n if (generator) {\r\n setMetaTag('generator', generator);\r\n }\r\n\r\n // Set revisit-after\r\n if (revisitAfter) {\r\n setMetaTag('revisit-after', revisitAfter);\r\n }\r\n\r\n // Set rating\r\n if (rating) {\r\n setMetaTag('rating', rating);\r\n }\r\n\r\n // Set distribution\r\n if (distribution) {\r\n setMetaTag('distribution', distribution);\r\n }\r\n\r\n // Set copyright\r\n if (copyright) {\r\n setMetaTag('copyright', copyright);\r\n }\r\n\r\n // Set theme-color\r\n if (themeColor) {\r\n setMetaTag('theme-color', themeColor);\r\n }\r\n\r\n // Set referrer\r\n if (referrer) {\r\n setMetaTag('referrer', referrer);\r\n }\r\n\r\n // Set format-detection\r\n if (formatDetection) {\r\n setMetaTag('format-detection', formatDetection);\r\n }\r\n\r\n // Set mobile-web-app-capable\r\n if (mobileWebAppCapable) {\r\n setMetaTag('mobile-web-app-capable', mobileWebAppCapable);\r\n }\r\n\r\n // Set apple-mobile-web-app-capable\r\n if (appleMobileWebAppCapable) {\r\n setMetaTag('apple-mobile-web-app-capable', appleMobileWebAppCapable);\r\n }\r\n\r\n // Set geo tags\r\n if (geoRegion) {\r\n setMetaTag('geo.region', geoRegion);\r\n }\r\n if (geoPlacename) {\r\n setMetaTag('geo.placename', geoPlacename);\r\n }\r\n if (geoPosition) {\r\n setMetaTag('geo.position', geoPosition);\r\n }\r\n if (icbm) {\r\n setMetaTag('ICBM', icbm);\r\n }\r\n\r\n // Set canonical URL\r\n if (canonical) {\r\n setCanonical(canonical);\r\n }\r\n\r\n // Build Open Graph object\r\n const ogData: any = {\r\n ...openGraph,\r\n };\r\n\r\n if (ogTitle || title) {\r\n ogData.title = ogTitle || title;\r\n }\r\n if (ogDescription || description) {\r\n ogData.description = ogDescription || description;\r\n }\r\n if (ogType) {\r\n ogData.type = ogType;\r\n }\r\n if (ogUrl || canonical) {\r\n ogData.url = ogUrl || canonical;\r\n }\r\n if (ogImage) {\r\n ogData.image = ogImage;\r\n }\r\n if (ogSiteName) {\r\n ogData.siteName = ogSiteName;\r\n }\r\n if (ogLocale) {\r\n ogData.locale = ogLocale;\r\n }\r\n\r\n if (Object.keys(ogData).length > 0) {\r\n setOpenGraphTags(ogData);\r\n }\r\n\r\n // Build Twitter Card object\r\n const twitterData: any = {\r\n ...twitter,\r\n };\r\n\r\n if (twitterCard) {\r\n twitterData.card = twitterCard;\r\n }\r\n if (twitterSite) {\r\n twitterData.site = twitterSite;\r\n }\r\n if (twitterCreator) {\r\n twitterData.creator = twitterCreator;\r\n }\r\n if (twitterTitle || title) {\r\n twitterData.title = twitterTitle || title;\r\n }\r\n if (twitterDescription || description) {\r\n twitterData.description = twitterDescription || description;\r\n }\r\n if (twitterImage || ogImage) {\r\n twitterData.image = twitterImage || ogImage;\r\n }\r\n if (twitterImageAlt) {\r\n twitterData.imageAlt = twitterImageAlt;\r\n }\r\n\r\n if (Object.keys(twitterData).length > 0) {\r\n setTwitterCardTags(twitterData);\r\n }\r\n\r\n // Set custom meta tags\r\n if (customMeta) {\r\n setCustomMetaTags(customMeta);\r\n }\r\n\r\n // Inject JSON-LD\r\n if (jsonLd) {\r\n injectJsonLd(jsonLd, JSON_LD_ID);\r\n }\r\n }, []);\r\n\r\n const clearSeo = useCallback(() => {\r\n // Note: We don't clear title, description, keywords as they might be set by other means\r\n // Only clear what we manage\r\n removeCanonical();\r\n removeJsonLd(JSON_LD_ID);\r\n }, []);\r\n\r\n return {\r\n updateSeo,\r\n clearSeo,\r\n };\r\n}\r\n\r\n"],"names":["getOrCreateMetaTag","attribute","value","selector","element","setMetaTag","name","content","setMetaProperty","property","setTitle","title","setCanonical","url","link","removeCanonical","setOpenGraphTags","og","key","setTwitterCardTags","twitter","setCustomMetaTags","customMeta","meta","charsetElement","injectJsonLd","data","id","script","existing","removeJsonLd","formatKeywords","keywords","JSON_LD_ID","Seo","description","author","robots","language","viewport","generator","revisitAfter","rating","distribution","copyright","themeColor","referrer","formatDetection","mobileWebAppCapable","appleMobileWebAppCapable","geoRegion","geoPlacename","geoPosition","icbm","canonical","ogImage","ogType","ogUrl","ogTitle","ogDescription","ogSiteName","ogLocale","twitterCard","twitterSite","twitterCreator","twitterTitle","twitterDescription","twitterImage","twitterImageAlt","jsonLd","openGraph","useEffect","keywordsStr","ogData","twitterData","cleanupJsonLd","useSeo","updateSeo","useCallback","props","clearSeo"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/utils.ts","../src/Seo.tsx","../src/useSeo.ts"],"sourcesContent":["import type { CustomMeta, CustomScript, JsonLd, OpenGraphMeta, TwitterCardMeta } from './types';\r\n\r\n/**\r\n * Get or create a meta tag element\r\n */\r\nfunction getOrCreateMetaTag(attribute: 'name' | 'property', value: string): HTMLMetaElement {\r\n const selector = `meta[${attribute}=\"${value}\"]`;\r\n let element = document.querySelector<HTMLMetaElement>(selector);\r\n\r\n if (!element) {\r\n element = document.createElement('meta');\r\n element.setAttribute(attribute, value);\r\n document.head.appendChild(element);\r\n }\r\n\r\n return element;\r\n}\r\n\r\n/**\r\n * Set a meta tag by name\r\n */\r\nexport function setMetaTag(name: string, content: string): void {\r\n if (!content) return;\r\n\r\n const element = getOrCreateMetaTag('name', name);\r\n element.setAttribute('content', content);\r\n}\r\n\r\n/**\r\n * Set a meta tag by property (for Open Graph)\r\n */\r\nexport function setMetaProperty(property: string, content: string | number): void {\r\n if (content === undefined || content === null || content === '') return;\r\n\r\n const element = getOrCreateMetaTag('property', property);\r\n element.setAttribute('content', String(content));\r\n}\r\n\r\n/**\r\n * Set the page title\r\n */\r\nexport function setTitle(title: string): void {\r\n if (!title) return;\r\n document.title = title;\r\n}\r\n\r\n/**\r\n * Set canonical URL\r\n */\r\nexport function setCanonical(url: string): void {\r\n if (!url) return;\r\n\r\n let link = document.querySelector<HTMLLinkElement>('link[rel=\"canonical\"]');\r\n if (!link) {\r\n link = document.createElement('link');\r\n link.setAttribute('rel', 'canonical');\r\n document.head.appendChild(link);\r\n }\r\n link.setAttribute('href', url);\r\n}\r\n\r\n/**\r\n * Remove canonical URL\r\n */\r\nexport function removeCanonical(): void {\r\n const link = document.querySelector<HTMLLinkElement>('link[rel=\"canonical\"]');\r\n if (link) {\r\n link.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Set Open Graph meta tags\r\n */\r\nexport function setOpenGraphTags(og: OpenGraphMeta): void {\r\n if (!og) return;\r\n\r\n // Standard Open Graph properties\r\n if (og.title) setMetaProperty('og:title', og.title);\r\n if (og.description) setMetaProperty('og:description', og.description);\r\n if (og.type) setMetaProperty('og:type', og.type);\r\n if (og.url) setMetaProperty('og:url', og.url);\r\n if (og.image) setMetaProperty('og:image', og.image);\r\n if (og.imageWidth) setMetaProperty('og:image:width', og.imageWidth);\r\n if (og.imageHeight) setMetaProperty('og:image:height', og.imageHeight);\r\n if (og.imageAlt) setMetaProperty('og:image:alt', og.imageAlt);\r\n if (og.siteName) setMetaProperty('og:site_name', og.siteName);\r\n if (og.locale) setMetaProperty('og:locale', og.locale);\r\n\r\n // Handle additional custom og:* properties\r\n Object.keys(og).forEach((key) => {\r\n if (key.startsWith('og:') && key !== 'og:title' && key !== 'og:description' && \r\n key !== 'og:type' && key !== 'og:url' && key !== 'og:image' && \r\n key !== 'og:imageWidth' && key !== 'og:imageHeight' && \r\n key !== 'og:imageAlt' && key !== 'og:siteName' && key !== 'og:locale') {\r\n const value = og[key as keyof OpenGraphMeta];\r\n if (value !== undefined && value !== null && value !== '') {\r\n setMetaProperty(key, value as string | number);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Set Twitter Card meta tags\r\n */\r\nexport function setTwitterCardTags(twitter: TwitterCardMeta): void {\r\n if (!twitter) return;\r\n\r\n if (twitter.card) setMetaTag('twitter:card', twitter.card);\r\n if (twitter.site) setMetaTag('twitter:site', twitter.site);\r\n if (twitter.creator) setMetaTag('twitter:creator', twitter.creator);\r\n if (twitter.title) setMetaTag('twitter:title', twitter.title);\r\n if (twitter.description) setMetaTag('twitter:description', twitter.description);\r\n if (twitter.image) setMetaTag('twitter:image', twitter.image);\r\n if (twitter.imageAlt) setMetaTag('twitter:image:alt', twitter.imageAlt);\r\n\r\n // Handle additional custom twitter:* properties\r\n Object.keys(twitter).forEach((key) => {\r\n if (key.startsWith('twitter:') && key !== 'twitter:card' && key !== 'twitter:site' && \r\n key !== 'twitter:creator' && key !== 'twitter:title' && \r\n key !== 'twitter:description' && key !== 'twitter:image' && \r\n key !== 'twitter:imageAlt') {\r\n const value = twitter[key as keyof TwitterCardMeta];\r\n if (value !== undefined && value !== null && value !== '') {\r\n setMetaTag(key, String(value));\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Set custom meta tags\r\n */\r\nexport function setCustomMetaTags(customMeta: CustomMeta[]): void {\r\n if (!customMeta || !Array.isArray(customMeta)) return;\r\n\r\n customMeta.forEach((meta) => {\r\n if (!meta.content) return;\r\n\r\n let element: HTMLMetaElement | null = null;\r\n\r\n if (meta.name) {\r\n element = getOrCreateMetaTag('name', meta.name);\r\n } else if (meta.property) {\r\n element = getOrCreateMetaTag('property', meta.property);\r\n } else if (meta.httpEquiv) {\r\n const selector = `meta[http-equiv=\"${meta.httpEquiv}\"]`;\r\n element = document.querySelector<HTMLMetaElement>(selector);\r\n if (!element) {\r\n element = document.createElement('meta');\r\n element.setAttribute('http-equiv', meta.httpEquiv);\r\n document.head.appendChild(element);\r\n }\r\n } else if (meta.charset) {\r\n let charsetElement = document.querySelector<HTMLMetaElement>('meta[charset]');\r\n if (!charsetElement) {\r\n charsetElement = document.createElement('meta');\r\n charsetElement.setAttribute('charset', meta.charset);\r\n document.head.insertBefore(charsetElement, document.head.firstChild);\r\n }\r\n return;\r\n }\r\n\r\n if (element) {\r\n element.setAttribute('content', meta.content);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Inject JSON-LD structured data\r\n */\r\nexport function injectJsonLd(data: JsonLd, id?: string): () => void {\r\n const script = document.createElement('script');\r\n script.type = 'application/ld+json';\r\n if (id) {\r\n script.id = id;\r\n // Remove existing script with same id\r\n const existing = document.getElementById(id);\r\n if (existing) {\r\n existing.remove();\r\n }\r\n }\r\n script.textContent = JSON.stringify(data);\r\n document.head.appendChild(script);\r\n\r\n // Return cleanup function\r\n return () => {\r\n script.remove();\r\n };\r\n}\r\n\r\n/**\r\n * Remove JSON-LD script by id\r\n */\r\nexport function removeJsonLd(id: string): void {\r\n const script = document.getElementById(id);\r\n if (script && script.getAttribute('type') === 'application/ld+json') {\r\n script.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Format keywords as string\r\n */\r\nexport function formatKeywords(keywords: string | string[] | undefined): string {\r\n if (!keywords) return '';\r\n if (Array.isArray(keywords)) {\r\n return keywords.join(', ');\r\n }\r\n return keywords;\r\n}\r\n\r\n/**\r\n * Remove script by id\r\n */\r\nexport function removeScript(id: string): void {\r\n const script = document.getElementById(id);\r\n if (script && script.tagName === 'SCRIPT') {\r\n script.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Inject Google Analytics script\r\n */\r\nexport function injectGoogleAnalytics(id: string): () => void {\r\n const GA_SCRIPT_ID = 'react-client-seo-ga';\r\n const GA_CONFIG_ID = 'react-client-seo-ga-config';\r\n\r\n // Remove existing scripts if present\r\n removeScript(GA_SCRIPT_ID);\r\n removeScript(GA_CONFIG_ID);\r\n\r\n // Inject gtag.js script\r\n const script = document.createElement('script');\r\n script.id = GA_SCRIPT_ID;\r\n script.async = true;\r\n script.src = `https://www.googletagmanager.com/gtag/js?id=${id}`;\r\n document.head.appendChild(script);\r\n\r\n // Inject gtag config script\r\n const configScript = document.createElement('script');\r\n configScript.id = GA_CONFIG_ID;\r\n configScript.textContent = `\r\n window.dataLayer = window.dataLayer || [];\r\n function gtag(){dataLayer.push(arguments);}\r\n gtag('js', new Date());\r\n gtag('config', '${id}');\r\n `;\r\n document.head.appendChild(configScript);\r\n\r\n // Return cleanup function\r\n return () => {\r\n removeScript(GA_SCRIPT_ID);\r\n removeScript(GA_CONFIG_ID);\r\n };\r\n}\r\n\r\n/**\r\n * Inject Google Tag Manager script\r\n */\r\nexport function injectGoogleTagManager(id: string): () => void {\r\n const GTM_SCRIPT_ID = 'react-client-seo-gtm';\r\n const GTM_NOSCRIPT_ID = 'react-client-seo-gtm-noscript';\r\n\r\n // Remove existing scripts if present\r\n removeScript(GTM_SCRIPT_ID);\r\n const existingNoscript = document.getElementById(GTM_NOSCRIPT_ID);\r\n if (existingNoscript) {\r\n existingNoscript.remove();\r\n }\r\n\r\n // Inject GTM script\r\n const script = document.createElement('script');\r\n script.id = GTM_SCRIPT_ID;\r\n script.textContent = `\r\n (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\r\n new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\r\n j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=\r\n 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\r\n })(window,document,'script','dataLayer','${id}');\r\n `;\r\n document.head.appendChild(script);\r\n\r\n // Inject GTM noscript (in body, but we'll add it to head with a marker)\r\n // Note: GTM noscript should ideally be in body, but for client-side rendering\r\n // we'll inject it and let the user know they may need to add it to body manually\r\n const noscript = document.createElement('noscript');\r\n noscript.id = GTM_NOSCRIPT_ID;\r\n noscript.innerHTML = `<iframe src=\"https://www.googletagmanager.com/ns.html?id=${id}\" height=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"></iframe>`;\r\n document.head.appendChild(noscript);\r\n\r\n // Return cleanup function\r\n return () => {\r\n removeScript(GTM_SCRIPT_ID);\r\n const noscriptEl = document.getElementById(GTM_NOSCRIPT_ID);\r\n if (noscriptEl) {\r\n noscriptEl.remove();\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Inject custom script\r\n */\r\nexport function injectCustomScript(scriptConfig: CustomScript): () => void {\r\n if (!scriptConfig.src && !scriptConfig.content) {\r\n console.warn('CustomScript must have either src or content');\r\n return () => {};\r\n }\r\n\r\n const scriptId = scriptConfig.id || `react-client-seo-custom-${Date.now()}`;\r\n\r\n // Remove existing script if present\r\n if (scriptConfig.id) {\r\n removeScript(scriptConfig.id);\r\n }\r\n\r\n const script = document.createElement('script');\r\n script.id = scriptId;\r\n\r\n if (scriptConfig.src) {\r\n script.src = scriptConfig.src;\r\n }\r\n\r\n if (scriptConfig.content) {\r\n script.textContent = scriptConfig.content;\r\n }\r\n\r\n // Set script attributes\r\n if (scriptConfig.type) {\r\n script.type = scriptConfig.type;\r\n } else {\r\n script.type = 'text/javascript';\r\n }\r\n\r\n if (scriptConfig.strategy === 'async' || scriptConfig.async) {\r\n script.async = true;\r\n }\r\n\r\n if (scriptConfig.strategy === 'defer' || scriptConfig.defer) {\r\n script.defer = true;\r\n }\r\n\r\n document.head.appendChild(script);\r\n\r\n // Return cleanup function\r\n return () => {\r\n removeScript(scriptId);\r\n };\r\n}\r\n","import { useEffect } from 'react';\r\nimport type { SeoProps } from './types';\r\nimport {\r\n setTitle,\r\n setMetaTag,\r\n setCanonical,\r\n setOpenGraphTags,\r\n setTwitterCardTags,\r\n setCustomMetaTags,\r\n injectJsonLd,\r\n formatKeywords,\r\n injectGoogleAnalytics,\r\n injectGoogleTagManager,\r\n injectCustomScript,\r\n} from './utils';\r\n\r\nconst JSON_LD_ID = 'react-client-seo-jsonld';\r\n\r\n/**\r\n * SEO Component\r\n * \r\n * Renders and updates SEO meta tags in the document head.\r\n * Returns null (no UI rendering).\r\n * \r\n * @example\r\n * ```tsx\r\n * <Seo\r\n * title=\"My Page Title\"\r\n * description=\"Page description\"\r\n * keywords={['react', 'seo']}\r\n * canonical=\"https://example.com/page\"\r\n * ogImage=\"https://example.com/image.jpg\"\r\n * jsonLd={{ \"@context\": \"https://schema.org\", \"@type\": \"WebPage\" }}\r\n * />\r\n * ```\r\n */\r\nexport function Seo({\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n googleAnalyticsId,\r\n googleTagManagerId,\r\n customScripts,\r\n}: SeoProps) {\r\n useEffect(() => {\r\n // Set title\r\n if (title) {\r\n setTitle(title);\r\n }\r\n\r\n // Set description\r\n if (description) {\r\n setMetaTag('description', description);\r\n }\r\n\r\n // Set keywords\r\n const keywordsStr = formatKeywords(keywords);\r\n if (keywordsStr) {\r\n setMetaTag('keywords', keywordsStr);\r\n }\r\n\r\n // Set author\r\n if (author) {\r\n setMetaTag('author', author);\r\n }\r\n\r\n // Set robots\r\n if (robots) {\r\n setMetaTag('robots', robots);\r\n }\r\n\r\n // Set language\r\n if (language) {\r\n setMetaTag('language', language);\r\n setMetaTag('content-language', language);\r\n }\r\n\r\n // Set viewport\r\n if (viewport) {\r\n setMetaTag('viewport', viewport);\r\n }\r\n\r\n // Set generator\r\n if (generator) {\r\n setMetaTag('generator', generator);\r\n }\r\n\r\n // Set revisit-after\r\n if (revisitAfter) {\r\n setMetaTag('revisit-after', revisitAfter);\r\n }\r\n\r\n // Set rating\r\n if (rating) {\r\n setMetaTag('rating', rating);\r\n }\r\n\r\n // Set distribution\r\n if (distribution) {\r\n setMetaTag('distribution', distribution);\r\n }\r\n\r\n // Set copyright\r\n if (copyright) {\r\n setMetaTag('copyright', copyright);\r\n }\r\n\r\n // Set theme-color\r\n if (themeColor) {\r\n setMetaTag('theme-color', themeColor);\r\n }\r\n\r\n // Set referrer\r\n if (referrer) {\r\n setMetaTag('referrer', referrer);\r\n }\r\n\r\n // Set format-detection\r\n if (formatDetection) {\r\n setMetaTag('format-detection', formatDetection);\r\n }\r\n\r\n // Set mobile-web-app-capable\r\n if (mobileWebAppCapable) {\r\n setMetaTag('mobile-web-app-capable', mobileWebAppCapable);\r\n }\r\n\r\n // Set apple-mobile-web-app-capable\r\n if (appleMobileWebAppCapable) {\r\n setMetaTag('apple-mobile-web-app-capable', appleMobileWebAppCapable);\r\n }\r\n\r\n // Set geo tags\r\n if (geoRegion) {\r\n setMetaTag('geo.region', geoRegion);\r\n }\r\n if (geoPlacename) {\r\n setMetaTag('geo.placename', geoPlacename);\r\n }\r\n if (geoPosition) {\r\n setMetaTag('geo.position', geoPosition);\r\n }\r\n if (icbm) {\r\n setMetaTag('ICBM', icbm);\r\n }\r\n\r\n // Set canonical URL\r\n if (canonical) {\r\n setCanonical(canonical);\r\n }\r\n\r\n // Build Open Graph object\r\n const ogData: any = {\r\n ...openGraph,\r\n };\r\n\r\n if (ogTitle || title) {\r\n ogData.title = ogTitle || title;\r\n }\r\n if (ogDescription || description) {\r\n ogData.description = ogDescription || description;\r\n }\r\n if (ogType) {\r\n ogData.type = ogType;\r\n }\r\n if (ogUrl || canonical) {\r\n ogData.url = ogUrl || canonical;\r\n }\r\n if (ogImage) {\r\n ogData.image = ogImage;\r\n }\r\n if (ogSiteName) {\r\n ogData.siteName = ogSiteName;\r\n }\r\n if (ogLocale) {\r\n ogData.locale = ogLocale;\r\n }\r\n\r\n if (Object.keys(ogData).length > 0) {\r\n setOpenGraphTags(ogData);\r\n }\r\n\r\n // Build Twitter Card object\r\n const twitterData: any = {\r\n ...twitter,\r\n };\r\n\r\n if (twitterCard) {\r\n twitterData.card = twitterCard;\r\n }\r\n if (twitterSite) {\r\n twitterData.site = twitterSite;\r\n }\r\n if (twitterCreator) {\r\n twitterData.creator = twitterCreator;\r\n }\r\n if (twitterTitle || title) {\r\n twitterData.title = twitterTitle || title;\r\n }\r\n if (twitterDescription || description) {\r\n twitterData.description = twitterDescription || description;\r\n }\r\n if (twitterImage || ogImage) {\r\n twitterData.image = twitterImage || ogImage;\r\n }\r\n if (twitterImageAlt) {\r\n twitterData.imageAlt = twitterImageAlt;\r\n }\r\n\r\n if (Object.keys(twitterData).length > 0) {\r\n setTwitterCardTags(twitterData);\r\n }\r\n\r\n // Set custom meta tags\r\n if (customMeta) {\r\n setCustomMetaTags(customMeta);\r\n }\r\n\r\n // Inject JSON-LD\r\n let cleanupJsonLd: (() => void) | null = null;\r\n if (jsonLd) {\r\n cleanupJsonLd = injectJsonLd(jsonLd, JSON_LD_ID);\r\n }\r\n\r\n // Inject Google Analytics\r\n let cleanupGA: (() => void) | null = null;\r\n if (googleAnalyticsId) {\r\n cleanupGA = injectGoogleAnalytics(googleAnalyticsId);\r\n }\r\n\r\n // Inject Google Tag Manager\r\n let cleanupGTM: (() => void) | null = null;\r\n if (googleTagManagerId) {\r\n cleanupGTM = injectGoogleTagManager(googleTagManagerId);\r\n }\r\n\r\n // Inject custom scripts\r\n const cleanupCustomScripts: (() => void)[] = [];\r\n if (customScripts && Array.isArray(customScripts)) {\r\n customScripts.forEach((scriptConfig) => {\r\n const cleanup = injectCustomScript(scriptConfig);\r\n cleanupCustomScripts.push(cleanup);\r\n });\r\n }\r\n\r\n // Cleanup function\r\n return () => {\r\n if (cleanupJsonLd) {\r\n cleanupJsonLd();\r\n }\r\n if (cleanupGA) {\r\n cleanupGA();\r\n }\r\n if (cleanupGTM) {\r\n cleanupGTM();\r\n }\r\n cleanupCustomScripts.forEach((cleanup) => cleanup());\r\n };\r\n }, [\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n googleAnalyticsId,\r\n googleTagManagerId,\r\n customScripts,\r\n ]);\r\n\r\n return null;\r\n}\r\n\r\n","import { useCallback } from 'react';\r\nimport type { SeoProps, UseSeoReturn } from './types';\r\nimport {\r\n setTitle,\r\n setMetaTag,\r\n setCanonical,\r\n setOpenGraphTags,\r\n setTwitterCardTags,\r\n setCustomMetaTags,\r\n injectJsonLd,\r\n formatKeywords,\r\n removeCanonical,\r\n removeJsonLd,\r\n injectGoogleAnalytics,\r\n injectGoogleTagManager,\r\n injectCustomScript,\r\n} from './utils';\r\n\r\nconst JSON_LD_ID = 'react-client-seo-jsonld';\r\n\r\n/**\r\n * useSeo Hook\r\n * \r\n * Hook-based API for managing SEO meta tags.\r\n * \r\n * @example\r\n * ```tsx\r\n * function MyComponent() {\r\n * const { updateSeo } = useSeo();\r\n * \r\n * useEffect(() => {\r\n * updateSeo({\r\n * title: 'My Page',\r\n * description: 'Page description',\r\n * });\r\n * }, []);\r\n * \r\n * return <div>Content</div>;\r\n * }\r\n * ```\r\n */\r\nexport function useSeo(): UseSeoReturn {\r\n const updateSeo = useCallback((props: SeoProps) => {\r\n const {\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n googleAnalyticsId,\r\n googleTagManagerId,\r\n customScripts,\r\n } = props;\r\n\r\n // Set title\r\n if (title) {\r\n setTitle(title);\r\n }\r\n\r\n // Set description\r\n if (description) {\r\n setMetaTag('description', description);\r\n }\r\n\r\n // Set keywords\r\n const keywordsStr = formatKeywords(keywords);\r\n if (keywordsStr) {\r\n setMetaTag('keywords', keywordsStr);\r\n }\r\n\r\n // Set author\r\n if (author) {\r\n setMetaTag('author', author);\r\n }\r\n\r\n // Set robots\r\n if (robots) {\r\n setMetaTag('robots', robots);\r\n }\r\n\r\n // Set language\r\n if (language) {\r\n setMetaTag('language', language);\r\n setMetaTag('content-language', language);\r\n }\r\n\r\n // Set viewport\r\n if (viewport) {\r\n setMetaTag('viewport', viewport);\r\n }\r\n\r\n // Set generator\r\n if (generator) {\r\n setMetaTag('generator', generator);\r\n }\r\n\r\n // Set revisit-after\r\n if (revisitAfter) {\r\n setMetaTag('revisit-after', revisitAfter);\r\n }\r\n\r\n // Set rating\r\n if (rating) {\r\n setMetaTag('rating', rating);\r\n }\r\n\r\n // Set distribution\r\n if (distribution) {\r\n setMetaTag('distribution', distribution);\r\n }\r\n\r\n // Set copyright\r\n if (copyright) {\r\n setMetaTag('copyright', copyright);\r\n }\r\n\r\n // Set theme-color\r\n if (themeColor) {\r\n setMetaTag('theme-color', themeColor);\r\n }\r\n\r\n // Set referrer\r\n if (referrer) {\r\n setMetaTag('referrer', referrer);\r\n }\r\n\r\n // Set format-detection\r\n if (formatDetection) {\r\n setMetaTag('format-detection', formatDetection);\r\n }\r\n\r\n // Set mobile-web-app-capable\r\n if (mobileWebAppCapable) {\r\n setMetaTag('mobile-web-app-capable', mobileWebAppCapable);\r\n }\r\n\r\n // Set apple-mobile-web-app-capable\r\n if (appleMobileWebAppCapable) {\r\n setMetaTag('apple-mobile-web-app-capable', appleMobileWebAppCapable);\r\n }\r\n\r\n // Set geo tags\r\n if (geoRegion) {\r\n setMetaTag('geo.region', geoRegion);\r\n }\r\n if (geoPlacename) {\r\n setMetaTag('geo.placename', geoPlacename);\r\n }\r\n if (geoPosition) {\r\n setMetaTag('geo.position', geoPosition);\r\n }\r\n if (icbm) {\r\n setMetaTag('ICBM', icbm);\r\n }\r\n\r\n // Set canonical URL\r\n if (canonical) {\r\n setCanonical(canonical);\r\n }\r\n\r\n // Build Open Graph object\r\n const ogData: any = {\r\n ...openGraph,\r\n };\r\n\r\n if (ogTitle || title) {\r\n ogData.title = ogTitle || title;\r\n }\r\n if (ogDescription || description) {\r\n ogData.description = ogDescription || description;\r\n }\r\n if (ogType) {\r\n ogData.type = ogType;\r\n }\r\n if (ogUrl || canonical) {\r\n ogData.url = ogUrl || canonical;\r\n }\r\n if (ogImage) {\r\n ogData.image = ogImage;\r\n }\r\n if (ogSiteName) {\r\n ogData.siteName = ogSiteName;\r\n }\r\n if (ogLocale) {\r\n ogData.locale = ogLocale;\r\n }\r\n\r\n if (Object.keys(ogData).length > 0) {\r\n setOpenGraphTags(ogData);\r\n }\r\n\r\n // Build Twitter Card object\r\n const twitterData: any = {\r\n ...twitter,\r\n };\r\n\r\n if (twitterCard) {\r\n twitterData.card = twitterCard;\r\n }\r\n if (twitterSite) {\r\n twitterData.site = twitterSite;\r\n }\r\n if (twitterCreator) {\r\n twitterData.creator = twitterCreator;\r\n }\r\n if (twitterTitle || title) {\r\n twitterData.title = twitterTitle || title;\r\n }\r\n if (twitterDescription || description) {\r\n twitterData.description = twitterDescription || description;\r\n }\r\n if (twitterImage || ogImage) {\r\n twitterData.image = twitterImage || ogImage;\r\n }\r\n if (twitterImageAlt) {\r\n twitterData.imageAlt = twitterImageAlt;\r\n }\r\n\r\n if (Object.keys(twitterData).length > 0) {\r\n setTwitterCardTags(twitterData);\r\n }\r\n\r\n // Set custom meta tags\r\n if (customMeta) {\r\n setCustomMetaTags(customMeta);\r\n }\r\n\r\n // Inject JSON-LD\r\n if (jsonLd) {\r\n injectJsonLd(jsonLd, JSON_LD_ID);\r\n }\r\n\r\n // Inject Google Analytics\r\n if (googleAnalyticsId) {\r\n injectGoogleAnalytics(googleAnalyticsId);\r\n }\r\n\r\n // Inject Google Tag Manager\r\n if (googleTagManagerId) {\r\n injectGoogleTagManager(googleTagManagerId);\r\n }\r\n\r\n // Inject custom scripts\r\n if (customScripts && Array.isArray(customScripts)) {\r\n customScripts.forEach((scriptConfig) => {\r\n injectCustomScript(scriptConfig);\r\n });\r\n }\r\n }, []);\r\n\r\n const clearSeo = useCallback(() => {\r\n // Note: We don't clear title, description, keywords as they might be set by other means\r\n // Only clear what we manage\r\n removeCanonical();\r\n removeJsonLd(JSON_LD_ID);\r\n }, []);\r\n\r\n return {\r\n updateSeo,\r\n clearSeo,\r\n };\r\n}\r\n\r\n"],"names":["getOrCreateMetaTag","attribute","value","selector","element","setMetaTag","name","content","setMetaProperty","property","setTitle","title","setCanonical","url","link","removeCanonical","setOpenGraphTags","og","key","setTwitterCardTags","twitter","setCustomMetaTags","customMeta","meta","charsetElement","injectJsonLd","data","id","script","existing","removeJsonLd","formatKeywords","keywords","removeScript","injectGoogleAnalytics","GA_SCRIPT_ID","GA_CONFIG_ID","configScript","injectGoogleTagManager","GTM_SCRIPT_ID","GTM_NOSCRIPT_ID","existingNoscript","noscript","noscriptEl","injectCustomScript","scriptConfig","scriptId","JSON_LD_ID","Seo","description","author","robots","language","viewport","generator","revisitAfter","rating","distribution","copyright","themeColor","referrer","formatDetection","mobileWebAppCapable","appleMobileWebAppCapable","geoRegion","geoPlacename","geoPosition","icbm","canonical","ogImage","ogType","ogUrl","ogTitle","ogDescription","ogSiteName","ogLocale","twitterCard","twitterSite","twitterCreator","twitterTitle","twitterDescription","twitterImage","twitterImageAlt","jsonLd","openGraph","googleAnalyticsId","googleTagManagerId","customScripts","useEffect","keywordsStr","ogData","twitterData","cleanupJsonLd","cleanupGA","cleanupGTM","cleanupCustomScripts","cleanup","useSeo","updateSeo","useCallback","props","clearSeo"],"mappings":"0GAKA,SAASA,EAAmBC,EAAgCC,EAAgC,CAC1F,MAAMC,EAAW,QAAQF,CAAS,KAAKC,CAAK,KAC5C,IAAIE,EAAU,SAAS,cAA+BD,CAAQ,EAE9D,OAAKC,IACHA,EAAU,SAAS,cAAc,MAAM,EACvCA,EAAQ,aAAaH,EAAWC,CAAK,EACrC,SAAS,KAAK,YAAYE,CAAO,GAG5BA,CACT,CAKO,SAASC,EAAWC,EAAcC,EAAuB,CAC9D,GAAI,CAACA,EAAS,OAEEP,EAAmB,OAAQM,CAAI,EACvC,aAAa,UAAWC,CAAO,CACzC,CAKO,SAASC,EAAgBC,EAAkBF,EAAgC,CAChF,GAA6BA,GAAY,MAAQA,IAAY,GAAI,OAEjDP,EAAmB,WAAYS,CAAQ,EAC/C,aAAa,UAAW,OAAOF,CAAO,CAAC,CACjD,CAKO,SAASG,GAASC,EAAqB,CACvCA,IACL,SAAS,MAAQA,EACnB,CAKO,SAASC,GAAaC,EAAmB,CAC9C,GAAI,CAACA,EAAK,OAEV,IAAIC,EAAO,SAAS,cAA+B,uBAAuB,EACrEA,IACHA,EAAO,SAAS,cAAc,MAAM,EACpCA,EAAK,aAAa,MAAO,WAAW,EACpC,SAAS,KAAK,YAAYA,CAAI,GAEhCA,EAAK,aAAa,OAAQD,CAAG,CAC/B,CAKO,SAASE,IAAwB,CACtC,MAAMD,EAAO,SAAS,cAA+B,uBAAuB,EACxEA,GACFA,EAAK,OAAA,CAET,CAKO,SAASE,GAAiBC,EAAyB,CACnDA,IAGDA,EAAG,OAAOT,EAAgB,WAAYS,EAAG,KAAK,EAC9CA,EAAG,aAAaT,EAAgB,iBAAkBS,EAAG,WAAW,EAChEA,EAAG,MAAMT,EAAgB,UAAWS,EAAG,IAAI,EAC3CA,EAAG,KAAKT,EAAgB,SAAUS,EAAG,GAAG,EACxCA,EAAG,OAAOT,EAAgB,WAAYS,EAAG,KAAK,EAC9CA,EAAG,YAAYT,EAAgB,iBAAkBS,EAAG,UAAU,EAC9DA,EAAG,aAAaT,EAAgB,kBAAmBS,EAAG,WAAW,EACjEA,EAAG,UAAUT,EAAgB,eAAgBS,EAAG,QAAQ,EACxDA,EAAG,UAAUT,EAAgB,eAAgBS,EAAG,QAAQ,EACxDA,EAAG,QAAQT,EAAgB,YAAaS,EAAG,MAAM,EAGrD,OAAO,KAAKA,CAAE,EAAE,QAASC,GAAQ,CAC/B,GAAIA,EAAI,WAAW,KAAK,GAAKA,IAAQ,YAAcA,IAAQ,kBACvDA,IAAQ,WAAaA,IAAQ,UAAYA,IAAQ,YACjDA,IAAQ,iBAAmBA,IAAQ,kBACnCA,IAAQ,eAAiBA,IAAQ,eAAiBA,IAAQ,YAAa,CACzE,MAAMhB,EAAQe,EAAGC,CAA0B,EAChBhB,GAAU,MAAQA,IAAU,IACrDM,EAAgBU,EAAKhB,CAAwB,CAEjD,CACF,CAAC,EACH,CAKO,SAASiB,GAAmBC,EAAgC,CAC5DA,IAEDA,EAAQ,MAAMf,EAAW,eAAgBe,EAAQ,IAAI,EACrDA,EAAQ,MAAMf,EAAW,eAAgBe,EAAQ,IAAI,EACrDA,EAAQ,SAASf,EAAW,kBAAmBe,EAAQ,OAAO,EAC9DA,EAAQ,OAAOf,EAAW,gBAAiBe,EAAQ,KAAK,EACxDA,EAAQ,aAAaf,EAAW,sBAAuBe,EAAQ,WAAW,EAC1EA,EAAQ,OAAOf,EAAW,gBAAiBe,EAAQ,KAAK,EACxDA,EAAQ,UAAUf,EAAW,oBAAqBe,EAAQ,QAAQ,EAGtE,OAAO,KAAKA,CAAO,EAAE,QAASF,GAAQ,CACpC,GAAIA,EAAI,WAAW,UAAU,GAAKA,IAAQ,gBAAkBA,IAAQ,gBAChEA,IAAQ,mBAAqBA,IAAQ,iBACrCA,IAAQ,uBAAyBA,IAAQ,iBACzCA,IAAQ,mBAAoB,CAC9B,MAAMhB,EAAQkB,EAAQF,CAA4B,EACvBhB,GAAU,MAAQA,IAAU,IACrDG,EAAWa,EAAK,OAAOhB,CAAK,CAAC,CAEjC,CACF,CAAC,EACH,CAKO,SAASmB,GAAkBC,EAAgC,CAC5D,CAACA,GAAc,CAAC,MAAM,QAAQA,CAAU,GAE5CA,EAAW,QAASC,GAAS,CAC3B,GAAI,CAACA,EAAK,QAAS,OAEnB,IAAInB,EAAkC,KAEtC,GAAImB,EAAK,KACPnB,EAAUJ,EAAmB,OAAQuB,EAAK,IAAI,UACrCA,EAAK,SACdnB,EAAUJ,EAAmB,WAAYuB,EAAK,QAAQ,UAC7CA,EAAK,UAAW,CACzB,MAAMpB,EAAW,oBAAoBoB,EAAK,SAAS,KACnDnB,EAAU,SAAS,cAA+BD,CAAQ,EACrDC,IACHA,EAAU,SAAS,cAAc,MAAM,EACvCA,EAAQ,aAAa,aAAcmB,EAAK,SAAS,EACjD,SAAS,KAAK,YAAYnB,CAAO,EAErC,SAAWmB,EAAK,QAAS,CACvB,IAAIC,EAAiB,SAAS,cAA+B,eAAe,EACvEA,IACHA,EAAiB,SAAS,cAAc,MAAM,EAC9CA,EAAe,aAAa,UAAWD,EAAK,OAAO,EACnD,SAAS,KAAK,aAAaC,EAAgB,SAAS,KAAK,UAAU,GAErE,MACF,CAEIpB,GACFA,EAAQ,aAAa,UAAWmB,EAAK,OAAO,CAEhD,CAAC,CACH,CAKO,SAASE,GAAaC,EAAcC,EAAyB,CAClE,MAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,KAAO,sBACN,CACNA,EAAO,GAAKD,EAEZ,MAAME,EAAW,SAAS,eAAeF,CAAE,EACvCE,GACFA,EAAS,OAAA,CAEb,CACA,OAAAD,EAAO,YAAc,KAAK,UAAUF,CAAI,EACxC,SAAS,KAAK,YAAYE,CAAM,EAGzB,IAAM,CACXA,EAAO,OAAA,CACT,CACF,CAKO,SAASE,GAAaH,EAAkB,CAC7C,MAAMC,EAAS,SAAS,eAAeD,CAAE,EACrCC,GAAUA,EAAO,aAAa,MAAM,IAAM,uBAC5CA,EAAO,OAAA,CAEX,CAKO,SAASG,GAAeC,EAAiD,CAC9E,OAAKA,EACD,MAAM,QAAQA,CAAQ,EACjBA,EAAS,KAAK,IAAI,EAEpBA,EAJe,EAKxB,CAKO,SAASC,EAAaN,EAAkB,CAC7C,MAAMC,EAAS,SAAS,eAAeD,CAAE,EACrCC,GAAUA,EAAO,UAAY,UAC/BA,EAAO,OAAA,CAEX,CAKO,SAASM,GAAsBP,EAAwB,CAC5D,MAAMQ,EAAe,sBACfC,EAAe,6BAGrBH,EAAaE,CAAY,EACzBF,EAAaG,CAAY,EAGzB,MAAMR,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,GAAKO,EACZP,EAAO,MAAQ,GACfA,EAAO,IAAM,+CAA+CD,CAAE,GAC9D,SAAS,KAAK,YAAYC,CAAM,EAGhC,MAAMS,EAAe,SAAS,cAAc,QAAQ,EACpD,OAAAA,EAAa,GAAKD,EAClBC,EAAa,YAAc;AAAA;AAAA;AAAA;AAAA,sBAIPV,CAAE;AAAA,IAEtB,SAAS,KAAK,YAAYU,CAAY,EAG/B,IAAM,CACXJ,EAAaE,CAAY,EACzBF,EAAaG,CAAY,CAC3B,CACF,CAKO,SAASE,GAAuBX,EAAwB,CAC7D,MAAMY,EAAgB,uBAChBC,EAAkB,gCAGxBP,EAAaM,CAAa,EAC1B,MAAME,EAAmB,SAAS,eAAeD,CAAe,EAC5DC,GACFA,EAAiB,OAAA,EAInB,MAAMb,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,GAAKW,EACZX,EAAO,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA,+CAKwBD,CAAE;AAAA,IAE/C,SAAS,KAAK,YAAYC,CAAM,EAKhC,MAAMc,EAAW,SAAS,cAAc,UAAU,EAClD,OAAAA,EAAS,GAAKF,EACdE,EAAS,UAAY,4DAA4Df,CAAE,0EACnF,SAAS,KAAK,YAAYe,CAAQ,EAG3B,IAAM,CACXT,EAAaM,CAAa,EAC1B,MAAMI,EAAa,SAAS,eAAeH,CAAe,EACtDG,GACFA,EAAW,OAAA,CAEf,CACF,CAKO,SAASC,GAAmBC,EAAwC,CACzE,GAAI,CAACA,EAAa,KAAO,CAACA,EAAa,QACrC,eAAQ,KAAK,8CAA8C,EACpD,IAAM,CAAC,EAGhB,MAAMC,EAAWD,EAAa,IAAM,2BAA2B,KAAK,KAAK,GAGrEA,EAAa,IACfZ,EAAaY,EAAa,EAAE,EAG9B,MAAMjB,EAAS,SAAS,cAAc,QAAQ,EAC9C,OAAAA,EAAO,GAAKkB,EAERD,EAAa,MACfjB,EAAO,IAAMiB,EAAa,KAGxBA,EAAa,UACfjB,EAAO,YAAciB,EAAa,SAIhCA,EAAa,KACfjB,EAAO,KAAOiB,EAAa,KAE3BjB,EAAO,KAAO,mBAGZiB,EAAa,WAAa,SAAWA,EAAa,SACpDjB,EAAO,MAAQ,KAGbiB,EAAa,WAAa,SAAWA,EAAa,SACpDjB,EAAO,MAAQ,IAGjB,SAAS,KAAK,YAAYA,CAAM,EAGzB,IAAM,CACXK,EAAaa,CAAQ,CACvB,CACF,CChVA,MAAMC,GAAa,0BAoBZ,SAASC,GAAI,CAClB,MAAArC,EACA,YAAAsC,EACA,SAAAjB,EACA,OAAAkB,EACA,OAAAC,EACA,SAAAC,EACA,SAAAC,EACA,UAAAC,EACA,aAAAC,EACA,OAAAC,EACA,aAAAC,EACA,UAAAC,EACA,WAAAC,EACA,SAAAC,EACA,gBAAAC,EACA,oBAAAC,EACA,yBAAAC,EACA,UAAAC,EACA,aAAAC,EACA,YAAAC,EACA,KAAAC,EACA,UAAAC,EACA,QAAAC,EACA,OAAAC,EACA,MAAAC,EACA,QAAAC,EACA,cAAAC,EACA,WAAAC,EACA,SAAAC,EACA,YAAAC,EACA,YAAAC,EACA,eAAAC,EACA,aAAAC,EACA,mBAAAC,EACA,aAAAC,EACA,gBAAAC,EACA,OAAAC,EACA,WAAA7D,EACA,UAAA8D,EACA,QAAAhE,EACA,kBAAAiE,EACA,mBAAAC,EACA,cAAAC,CACF,EAAa,CACXC,OAAAA,GAAAA,UAAU,IAAM,CAEV7E,GACFD,GAASC,CAAK,EAIZsC,GACF5C,EAAW,cAAe4C,CAAW,EAIvC,MAAMwC,EAAc1D,GAAeC,CAAQ,EACvCyD,GACFpF,EAAW,WAAYoF,CAAW,EAIhCvC,GACF7C,EAAW,SAAU6C,CAAM,EAIzBC,GACF9C,EAAW,SAAU8C,CAAM,EAIzBC,IACF/C,EAAW,WAAY+C,CAAQ,EAC/B/C,EAAW,mBAAoB+C,CAAQ,GAIrCC,GACFhD,EAAW,WAAYgD,CAAQ,EAI7BC,GACFjD,EAAW,YAAaiD,CAAS,EAI/BC,GACFlD,EAAW,gBAAiBkD,CAAY,EAItCC,GACFnD,EAAW,SAAUmD,CAAM,EAIzBC,GACFpD,EAAW,eAAgBoD,CAAY,EAIrCC,GACFrD,EAAW,YAAaqD,CAAS,EAI/BC,GACFtD,EAAW,cAAesD,CAAU,EAIlCC,GACFvD,EAAW,WAAYuD,CAAQ,EAI7BC,GACFxD,EAAW,mBAAoBwD,CAAe,EAI5CC,GACFzD,EAAW,yBAA0ByD,CAAmB,EAItDC,GACF1D,EAAW,+BAAgC0D,CAAwB,EAIjEC,GACF3D,EAAW,aAAc2D,CAAS,EAEhCC,GACF5D,EAAW,gBAAiB4D,CAAY,EAEtCC,GACF7D,EAAW,eAAgB6D,CAAW,EAEpCC,GACF9D,EAAW,OAAQ8D,CAAI,EAIrBC,GACFxD,GAAawD,CAAS,EAIxB,MAAMsB,EAAc,CAClB,GAAGN,CAAA,GAGDZ,GAAW7D,KACb+E,EAAO,MAAQlB,GAAW7D,IAExB8D,GAAiBxB,KACnByC,EAAO,YAAcjB,GAAiBxB,GAEpCqB,IACFoB,EAAO,KAAOpB,IAEZC,GAASH,KACXsB,EAAO,IAAMnB,GAASH,GAEpBC,IACFqB,EAAO,MAAQrB,GAEbK,IACFgB,EAAO,SAAWhB,GAEhBC,IACFe,EAAO,OAASf,GAGd,OAAO,KAAKe,CAAM,EAAE,OAAS,GAC/B1E,GAAiB0E,CAAM,EAIzB,MAAMC,EAAmB,CACvB,GAAGvE,CAAA,EAGDwD,IACFe,EAAY,KAAOf,GAEjBC,IACFc,EAAY,KAAOd,GAEjBC,IACFa,EAAY,QAAUb,IAEpBC,GAAgBpE,KAClBgF,EAAY,MAAQZ,GAAgBpE,IAElCqE,GAAsB/B,KACxB0C,EAAY,YAAcX,GAAsB/B,IAE9CgC,GAAgBZ,KAClBsB,EAAY,MAAQV,GAAgBZ,GAElCa,IACFS,EAAY,SAAWT,GAGrB,OAAO,KAAKS,CAAW,EAAE,OAAS,GACpCxE,GAAmBwE,CAAW,EAI5BrE,GACFD,GAAkBC,CAAU,EAI9B,IAAIsE,EAAqC,KACrCT,IACFS,EAAgBnE,GAAa0D,EAAQpC,EAAU,GAIjD,IAAI8C,EAAiC,KACjCR,IACFQ,EAAY3D,GAAsBmD,CAAiB,GAIrD,IAAIS,EAAkC,KAClCR,IACFQ,EAAaxD,GAAuBgD,CAAkB,GAIxD,MAAMS,EAAuC,CAAA,EAC7C,OAAIR,GAAiB,MAAM,QAAQA,CAAa,GAC9CA,EAAc,QAAS1C,IAAiB,CACtC,MAAMmD,GAAUpD,GAAmBC,EAAY,EAC/CkD,EAAqB,KAAKC,EAAO,CACnC,CAAC,EAII,IAAM,CACPJ,GACFA,EAAA,EAEEC,GACFA,EAAA,EAEEC,GACFA,EAAA,EAEFC,EAAqB,QAASC,IAAYA,GAAA,CAAS,CACrD,CACF,EAAG,CACDrF,EACAsC,EACAjB,EACAkB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACA7D,EACA8D,EACAhE,EACAiE,EACAC,EACAC,CAAA,CACD,EAEM,IACT,CCpUA,MAAMxC,GAAa,0BAuBZ,SAASkD,IAAuB,CACrC,MAAMC,EAAYC,eAAaC,GAAoB,CACjD,KAAM,CACJ,MAAAzF,EACA,YAAAsC,EACA,SAAAjB,EACA,OAAAkB,EACA,OAAAC,EACA,SAAAC,EACA,SAAAC,EACA,UAAAC,EACA,aAAAC,EACA,OAAAC,EACA,aAAAC,EACA,UAAAC,EACA,WAAAC,EACA,SAAAC,EACA,gBAAAC,EACA,oBAAAC,EACA,yBAAAC,EACA,UAAAC,EACA,aAAAC,EACA,YAAAC,EACA,KAAAC,EACA,UAAAC,EACA,QAAAC,EACA,OAAAC,EACA,MAAAC,EACA,QAAAC,EACA,cAAAC,EACA,WAAAC,EACA,SAAAC,EACA,YAAAC,EACA,YAAAC,EACA,eAAAC,EACA,aAAAC,EACA,mBAAAC,EACA,aAAAC,EACA,gBAAAC,EACA,OAAAC,EACA,WAAA7D,EACA,UAAA8D,EACA,QAAAhE,EACA,kBAAAiE,EACA,mBAAAC,EACA,cAAAC,CAAA,EACEa,EAGAzF,GACFD,GAASC,CAAK,EAIZsC,GACF5C,EAAW,cAAe4C,CAAW,EAIvC,MAAMwC,EAAc1D,GAAeC,CAAQ,EACvCyD,GACFpF,EAAW,WAAYoF,CAAW,EAIhCvC,GACF7C,EAAW,SAAU6C,CAAM,EAIzBC,GACF9C,EAAW,SAAU8C,CAAM,EAIzBC,IACF/C,EAAW,WAAY+C,CAAQ,EAC/B/C,EAAW,mBAAoB+C,CAAQ,GAIrCC,GACFhD,EAAW,WAAYgD,CAAQ,EAI7BC,GACFjD,EAAW,YAAaiD,CAAS,EAI/BC,GACFlD,EAAW,gBAAiBkD,CAAY,EAItCC,GACFnD,EAAW,SAAUmD,CAAM,EAIzBC,GACFpD,EAAW,eAAgBoD,CAAY,EAIrCC,GACFrD,EAAW,YAAaqD,CAAS,EAI/BC,GACFtD,EAAW,cAAesD,CAAU,EAIlCC,GACFvD,EAAW,WAAYuD,CAAQ,EAI7BC,GACFxD,EAAW,mBAAoBwD,CAAe,EAI5CC,GACFzD,EAAW,yBAA0ByD,CAAmB,EAItDC,GACF1D,EAAW,+BAAgC0D,CAAwB,EAIjEC,GACF3D,EAAW,aAAc2D,CAAS,EAEhCC,GACF5D,EAAW,gBAAiB4D,CAAY,EAEtCC,GACF7D,EAAW,eAAgB6D,CAAW,EAEpCC,GACF9D,EAAW,OAAQ8D,CAAI,EAIrBC,GACFxD,GAAawD,CAAS,EAIxB,MAAMsB,EAAc,CAClB,GAAGN,CAAA,GAGDZ,GAAW7D,KACb+E,EAAO,MAAQlB,GAAW7D,IAExB8D,GAAiBxB,KACnByC,EAAO,YAAcjB,GAAiBxB,GAEpCqB,IACFoB,EAAO,KAAOpB,IAEZC,GAASH,KACXsB,EAAO,IAAMnB,GAASH,GAEpBC,IACFqB,EAAO,MAAQrB,GAEbK,IACFgB,EAAO,SAAWhB,GAEhBC,IACFe,EAAO,OAASf,GAGd,OAAO,KAAKe,CAAM,EAAE,OAAS,GAC/B1E,GAAiB0E,CAAM,EAIzB,MAAMC,EAAmB,CACvB,GAAGvE,CAAA,EAGDwD,IACFe,EAAY,KAAOf,GAEjBC,IACFc,EAAY,KAAOd,GAEjBC,IACFa,EAAY,QAAUb,IAEpBC,GAAgBpE,KAClBgF,EAAY,MAAQZ,GAAgBpE,IAElCqE,GAAsB/B,KACxB0C,EAAY,YAAcX,GAAsB/B,IAE9CgC,GAAgBZ,KAClBsB,EAAY,MAAQV,GAAgBZ,GAElCa,IACFS,EAAY,SAAWT,GAGrB,OAAO,KAAKS,CAAW,EAAE,OAAS,GACpCxE,GAAmBwE,CAAW,EAI5BrE,GACFD,GAAkBC,CAAU,EAI1B6D,GACF1D,GAAa0D,EAAQpC,EAAU,EAI7BsC,GACFnD,GAAsBmD,CAAiB,EAIrCC,GACFhD,GAAuBgD,CAAkB,EAIvCC,GAAiB,MAAM,QAAQA,CAAa,GAC9CA,EAAc,QAAS1C,GAAiB,CACtCD,GAAmBC,CAAY,CACjC,CAAC,CAEL,EAAG,CAAA,CAAE,EAECwD,EAAWF,GAAAA,YAAY,IAAM,CAGjCpF,GAAA,EACAe,GAAaiB,EAAU,CACzB,EAAG,CAAA,CAAE,EAEL,MAAO,CACL,UAAAmD,EACA,SAAAG,CAAA,CAEJ"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { Seo } from './Seo';
2
2
  export { useSeo } from './useSeo';
3
- export type { SeoProps, OpenGraphMeta, TwitterCardMeta, CustomMeta, JsonLd, UseSeoReturn, } from './types';
3
+ export type { SeoProps, OpenGraphMeta, TwitterCardMeta, CustomMeta, CustomScript, JsonLd, UseSeoReturn, } from './types';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EACV,QAAQ,EACR,aAAa,EACb,eAAe,EACf,UAAU,EACV,MAAM,EACN,YAAY,GACb,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EACV,QAAQ,EACR,aAAa,EACb,eAAe,EACf,UAAU,EACV,YAAY,EACZ,MAAM,EACN,YAAY,GACb,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,243 +1,313 @@
1
- import { useEffect as re, useCallback as Z } from "react";
2
- function Y(e, t) {
3
- const n = `meta[${e}="${t}"]`;
4
- let r = document.querySelector(n);
1
+ import { useEffect as pe, useCallback as te } from "react";
2
+ function k(e, t) {
3
+ const i = `meta[${e}="${t}"]`;
4
+ let r = document.querySelector(i);
5
5
  return r || (r = document.createElement("meta"), r.setAttribute(e, t), document.head.appendChild(r)), r;
6
6
  }
7
- function i(e, t) {
7
+ function n(e, t) {
8
8
  if (!t) return;
9
- Y("name", e).setAttribute("content", t);
9
+ k("name", e).setAttribute("content", t);
10
10
  }
11
- function a(e, t) {
11
+ function l(e, t) {
12
12
  if (t == null || t === "") return;
13
- Y("property", e).setAttribute("content", String(t));
13
+ k("property", e).setAttribute("content", String(t));
14
14
  }
15
- function R(e) {
15
+ function ne(e) {
16
16
  e && (document.title = e);
17
17
  }
18
- function U(e) {
18
+ function re(e) {
19
19
  if (!e) return;
20
20
  let t = document.querySelector('link[rel="canonical"]');
21
21
  t || (t = document.createElement("link"), t.setAttribute("rel", "canonical"), document.head.appendChild(t)), t.setAttribute("href", e);
22
22
  }
23
- function fe() {
23
+ function ge() {
24
24
  const e = document.querySelector('link[rel="canonical"]');
25
25
  e && e.remove();
26
26
  }
27
- function k(e) {
28
- e && (e.title && a("og:title", e.title), e.description && a("og:description", e.description), e.type && a("og:type", e.type), e.url && a("og:url", e.url), e.image && a("og:image", e.image), e.imageWidth && a("og:image:width", e.imageWidth), e.imageHeight && a("og:image:height", e.imageHeight), e.imageAlt && a("og:image:alt", e.imageAlt), e.siteName && a("og:site_name", e.siteName), e.locale && a("og:locale", e.locale), Object.keys(e).forEach((t) => {
27
+ function ae(e) {
28
+ e && (e.title && l("og:title", e.title), e.description && l("og:description", e.description), e.type && l("og:type", e.type), e.url && l("og:url", e.url), e.image && l("og:image", e.image), e.imageWidth && l("og:image:width", e.imageWidth), e.imageHeight && l("og:image:height", e.imageHeight), e.imageAlt && l("og:image:alt", e.imageAlt), e.siteName && l("og:site_name", e.siteName), e.locale && l("og:locale", e.locale), Object.keys(e).forEach((t) => {
29
29
  if (t.startsWith("og:") && t !== "og:title" && t !== "og:description" && t !== "og:type" && t !== "og:url" && t !== "og:image" && t !== "og:imageWidth" && t !== "og:imageHeight" && t !== "og:imageAlt" && t !== "og:siteName" && t !== "og:locale") {
30
- const n = e[t];
31
- n != null && n !== "" && a(t, n);
30
+ const i = e[t];
31
+ i != null && i !== "" && l(t, i);
32
32
  }
33
33
  }));
34
34
  }
35
- function ee(e) {
36
- e && (e.card && i("twitter:card", e.card), e.site && i("twitter:site", e.site), e.creator && i("twitter:creator", e.creator), e.title && i("twitter:title", e.title), e.description && i("twitter:description", e.description), e.image && i("twitter:image", e.image), e.imageAlt && i("twitter:image:alt", e.imageAlt), Object.keys(e).forEach((t) => {
35
+ function ce(e) {
36
+ e && (e.card && n("twitter:card", e.card), e.site && n("twitter:site", e.site), e.creator && n("twitter:creator", e.creator), e.title && n("twitter:title", e.title), e.description && n("twitter:description", e.description), e.image && n("twitter:image", e.image), e.imageAlt && n("twitter:image:alt", e.imageAlt), Object.keys(e).forEach((t) => {
37
37
  if (t.startsWith("twitter:") && t !== "twitter:card" && t !== "twitter:site" && t !== "twitter:creator" && t !== "twitter:title" && t !== "twitter:description" && t !== "twitter:image" && t !== "twitter:imageAlt") {
38
- const n = e[t];
39
- n != null && n !== "" && i(t, String(n));
38
+ const i = e[t];
39
+ i != null && i !== "" && n(t, String(i));
40
40
  }
41
41
  }));
42
42
  }
43
- function te(e) {
43
+ function oe(e) {
44
44
  !e || !Array.isArray(e) || e.forEach((t) => {
45
45
  if (!t.content) return;
46
- let n = null;
46
+ let i = null;
47
47
  if (t.name)
48
- n = Y("name", t.name);
48
+ i = k("name", t.name);
49
49
  else if (t.property)
50
- n = Y("property", t.property);
50
+ i = k("property", t.property);
51
51
  else if (t.httpEquiv) {
52
52
  const r = `meta[http-equiv="${t.httpEquiv}"]`;
53
- n = document.querySelector(r), n || (n = document.createElement("meta"), n.setAttribute("http-equiv", t.httpEquiv), document.head.appendChild(n));
53
+ i = document.querySelector(r), i || (i = document.createElement("meta"), i.setAttribute("http-equiv", t.httpEquiv), document.head.appendChild(i));
54
54
  } else if (t.charset) {
55
55
  let r = document.querySelector("meta[charset]");
56
56
  r || (r = document.createElement("meta"), r.setAttribute("charset", t.charset), document.head.insertBefore(r, document.head.firstChild));
57
57
  return;
58
58
  }
59
- n && n.setAttribute("content", t.content);
59
+ i && i.setAttribute("content", t.content);
60
60
  });
61
61
  }
62
- function ie(e, t) {
63
- const n = document.createElement("script");
64
- n.type = "application/ld+json";
62
+ function fe(e, t) {
63
+ const i = document.createElement("script");
64
+ i.type = "application/ld+json";
65
65
  {
66
- n.id = t;
66
+ i.id = t;
67
67
  const r = document.getElementById(t);
68
68
  r && r.remove();
69
69
  }
70
- return n.textContent = JSON.stringify(e), document.head.appendChild(n), () => {
71
- n.remove();
70
+ return i.textContent = JSON.stringify(e), document.head.appendChild(i), () => {
71
+ i.remove();
72
72
  };
73
73
  }
74
- function oe(e) {
74
+ function he(e) {
75
75
  const t = document.getElementById(e);
76
76
  t && t.getAttribute("type") === "application/ld+json" && t.remove();
77
77
  }
78
- function ne(e) {
78
+ function se(e) {
79
79
  return e ? Array.isArray(e) ? e.join(", ") : e : "";
80
80
  }
81
- const ae = "react-client-seo-jsonld";
82
- function le({
81
+ function y(e) {
82
+ const t = document.getElementById(e);
83
+ t && t.tagName === "SCRIPT" && t.remove();
84
+ }
85
+ function le(e) {
86
+ const t = "react-client-seo-ga", i = "react-client-seo-ga-config";
87
+ y(t), y(i);
88
+ const r = document.createElement("script");
89
+ r.id = t, r.async = !0, r.src = `https://www.googletagmanager.com/gtag/js?id=${e}`, document.head.appendChild(r);
90
+ const a = document.createElement("script");
91
+ return a.id = i, a.textContent = `
92
+ window.dataLayer = window.dataLayer || [];
93
+ function gtag(){dataLayer.push(arguments);}
94
+ gtag('js', new Date());
95
+ gtag('config', '${e}');
96
+ `, document.head.appendChild(a), () => {
97
+ y(t), y(i);
98
+ };
99
+ }
100
+ function de(e) {
101
+ const t = "react-client-seo-gtm", i = "react-client-seo-gtm-noscript";
102
+ y(t);
103
+ const r = document.getElementById(i);
104
+ r && r.remove();
105
+ const a = document.createElement("script");
106
+ a.id = t, a.textContent = `
107
+ (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
108
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
109
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
110
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
111
+ })(window,document,'script','dataLayer','${e}');
112
+ `, document.head.appendChild(a);
113
+ const d = document.createElement("noscript");
114
+ return d.id = i, d.innerHTML = `<iframe src="https://www.googletagmanager.com/ns.html?id=${e}" height="0" width="0" style="display:none;visibility:hidden"></iframe>`, document.head.appendChild(d), () => {
115
+ y(t);
116
+ const u = document.getElementById(i);
117
+ u && u.remove();
118
+ };
119
+ }
120
+ function ue(e) {
121
+ if (!e.src && !e.content)
122
+ return console.warn("CustomScript must have either src or content"), () => {
123
+ };
124
+ const t = e.id || `react-client-seo-custom-${Date.now()}`;
125
+ e.id && y(e.id);
126
+ const i = document.createElement("script");
127
+ return i.id = t, e.src && (i.src = e.src), e.content && (i.textContent = e.content), e.type ? i.type = e.type : i.type = "text/javascript", (e.strategy === "async" || e.async) && (i.async = !0), (e.strategy === "defer" || e.defer) && (i.defer = !0), document.head.appendChild(i), () => {
128
+ y(t);
129
+ };
130
+ }
131
+ const ye = "react-client-seo-jsonld";
132
+ function we({
83
133
  title: e,
84
134
  description: t,
85
- keywords: n,
135
+ keywords: i,
86
136
  author: r,
87
- robots: c,
88
- language: h,
89
- viewport: b,
90
- generator: v,
91
- revisitAfter: g,
92
- rating: A,
93
- distribution: E,
94
- copyright: S,
95
- themeColor: y,
96
- referrer: j,
97
- formatDetection: O,
98
- mobileWebAppCapable: q,
99
- appleMobileWebAppCapable: C,
100
- geoRegion: N,
101
- geoPlacename: J,
102
- geoPosition: B,
103
- icbm: D,
104
- canonical: u,
105
- ogImage: m,
106
- ogType: _,
107
- ogUrl: d,
108
- ogTitle: p,
109
- ogDescription: T,
110
- ogSiteName: $,
111
- ogLocale: w,
112
- twitterCard: x,
113
- twitterSite: H,
114
- twitterCreator: L,
115
- twitterTitle: W,
116
- twitterDescription: M,
117
- twitterImage: G,
118
- twitterImageAlt: I,
119
- jsonLd: K,
120
- customMeta: z,
121
- openGraph: Q,
122
- twitter: V
137
+ robots: a,
138
+ language: d,
139
+ viewport: u,
140
+ generator: w,
141
+ revisitAfter: E,
142
+ rating: v,
143
+ distribution: A,
144
+ copyright: b,
145
+ themeColor: j,
146
+ referrer: S,
147
+ formatDetection: T,
148
+ mobileWebAppCapable: N,
149
+ appleMobileWebAppCapable: O,
150
+ geoRegion: _,
151
+ geoPlacename: D,
152
+ geoPosition: I,
153
+ icbm: C,
154
+ canonical: m,
155
+ ogImage: p,
156
+ ogType: q,
157
+ ogUrl: g,
158
+ ogTitle: h,
159
+ ogDescription: B,
160
+ ogSiteName: G,
161
+ ogLocale: L,
162
+ twitterCard: $,
163
+ twitterSite: x,
164
+ twitterCreator: J,
165
+ twitterTitle: M,
166
+ twitterDescription: H,
167
+ twitterImage: P,
168
+ twitterImageAlt: R,
169
+ jsonLd: W,
170
+ customMeta: F,
171
+ openGraph: V,
172
+ twitter: X,
173
+ googleAnalyticsId: K,
174
+ googleTagManagerId: Y,
175
+ customScripts: z
123
176
  }) {
124
- return re(() => {
125
- e && R(e), t && i("description", t);
126
- const X = ne(n);
127
- X && i("keywords", X), r && i("author", r), c && i("robots", c), h && (i("language", h), i("content-language", h)), b && i("viewport", b), v && i("generator", v), g && i("revisit-after", g), A && i("rating", A), E && i("distribution", E), S && i("copyright", S), y && i("theme-color", y), j && i("referrer", j), O && i("format-detection", O), q && i("mobile-web-app-capable", q), C && i("apple-mobile-web-app-capable", C), N && i("geo.region", N), J && i("geo.placename", J), B && i("geo.position", B), D && i("ICBM", D), u && U(u);
128
- const f = {
129
- ...Q
130
- };
131
- (p || e) && (f.title = p || e), (T || t) && (f.description = T || t), _ && (f.type = _), (d || u) && (f.url = d || u), m && (f.image = m), $ && (f.siteName = $), w && (f.locale = w), Object.keys(f).length > 0 && k(f);
132
- const o = {
177
+ return pe(() => {
178
+ e && ne(e), t && n("description", t);
179
+ const Z = se(i);
180
+ Z && n("keywords", Z), r && n("author", r), a && n("robots", a), d && (n("language", d), n("content-language", d)), u && n("viewport", u), w && n("generator", w), E && n("revisit-after", E), v && n("rating", v), A && n("distribution", A), b && n("copyright", b), j && n("theme-color", j), S && n("referrer", S), T && n("format-detection", T), N && n("mobile-web-app-capable", N), O && n("apple-mobile-web-app-capable", O), _ && n("geo.region", _), D && n("geo.placename", D), I && n("geo.position", I), C && n("ICBM", C), m && re(m);
181
+ const s = {
133
182
  ...V
134
183
  };
135
- x && (o.card = x), H && (o.site = H), L && (o.creator = L), (W || e) && (o.title = W || e), (M || t) && (o.description = M || t), (G || m) && (o.image = G || m), I && (o.imageAlt = I), Object.keys(o).length > 0 && ee(o), z && te(z);
136
- let F = null;
137
- return K && (F = ie(K, ae)), () => {
138
- F && F();
184
+ (h || e) && (s.title = h || e), (B || t) && (s.description = B || t), q && (s.type = q), (g || m) && (s.url = g || m), p && (s.image = p), G && (s.siteName = G), L && (s.locale = L), Object.keys(s).length > 0 && ae(s);
185
+ const c = {
186
+ ...X
187
+ };
188
+ $ && (c.card = $), x && (c.site = x), J && (c.creator = J), (M || e) && (c.title = M || e), (H || t) && (c.description = H || t), (P || p) && (c.image = P || p), R && (c.imageAlt = R), Object.keys(c).length > 0 && ce(c), F && oe(F);
189
+ let Q = null;
190
+ W && (Q = fe(W, ye));
191
+ let o = null;
192
+ K && (o = le(K));
193
+ let f = null;
194
+ Y && (f = de(Y));
195
+ const U = [];
196
+ return z && Array.isArray(z) && z.forEach((ee) => {
197
+ const me = ue(ee);
198
+ U.push(me);
199
+ }), () => {
200
+ Q && Q(), o && o(), f && f(), U.forEach((ee) => ee());
139
201
  };
140
202
  }, [
141
203
  e,
142
204
  t,
143
- n,
205
+ i,
144
206
  r,
145
- c,
146
- h,
147
- b,
207
+ a,
208
+ d,
209
+ u,
210
+ w,
211
+ E,
148
212
  v,
149
- g,
150
213
  A,
151
- E,
152
- S,
153
- y,
214
+ b,
154
215
  j,
155
- O,
156
- q,
157
- C,
216
+ S,
217
+ T,
158
218
  N,
159
- J,
160
- B,
219
+ O,
220
+ _,
161
221
  D,
162
- u,
222
+ I,
223
+ C,
163
224
  m,
164
- _,
165
- d,
166
225
  p,
167
- T,
226
+ q,
227
+ g,
228
+ h,
229
+ B,
230
+ G,
231
+ L,
168
232
  $,
169
- w,
170
233
  x,
234
+ J,
235
+ M,
171
236
  H,
172
- L,
237
+ P,
238
+ R,
173
239
  W,
174
- M,
175
- G,
176
- I,
240
+ F,
241
+ V,
242
+ X,
177
243
  K,
178
- z,
179
- Q,
180
- V
244
+ Y,
245
+ z
181
246
  ]), null;
182
247
  }
183
- const P = "react-client-seo-jsonld";
184
- function se() {
185
- const e = Z((n) => {
248
+ const ie = "react-client-seo-jsonld";
249
+ function ve() {
250
+ const e = te((i) => {
186
251
  const {
187
252
  title: r,
188
- description: c,
189
- keywords: h,
190
- author: b,
191
- robots: v,
192
- language: g,
193
- viewport: A,
194
- generator: E,
195
- revisitAfter: S,
196
- rating: y,
197
- distribution: j,
198
- copyright: O,
199
- themeColor: q,
200
- referrer: C,
201
- formatDetection: N,
202
- mobileWebAppCapable: J,
203
- appleMobileWebAppCapable: B,
204
- geoRegion: D,
205
- geoPlacename: u,
206
- geoPosition: m,
207
- icbm: _,
208
- canonical: d,
209
- ogImage: p,
210
- ogType: T,
211
- ogUrl: $,
212
- ogTitle: w,
213
- ogDescription: x,
214
- ogSiteName: H,
215
- ogLocale: L,
216
- twitterCard: W,
217
- twitterSite: M,
218
- twitterCreator: G,
219
- twitterTitle: I,
220
- twitterDescription: K,
221
- twitterImage: z,
222
- twitterImageAlt: Q,
223
- jsonLd: V,
224
- customMeta: X,
225
- openGraph: f,
226
- twitter: o
227
- } = n;
228
- r && R(r), c && i("description", c);
229
- const F = ne(h);
230
- F && i("keywords", F), b && i("author", b), v && i("robots", v), g && (i("language", g), i("content-language", g)), A && i("viewport", A), E && i("generator", E), S && i("revisit-after", S), y && i("rating", y), j && i("distribution", j), O && i("copyright", O), q && i("theme-color", q), C && i("referrer", C), N && i("format-detection", N), J && i("mobile-web-app-capable", J), B && i("apple-mobile-web-app-capable", B), D && i("geo.region", D), u && i("geo.placename", u), m && i("geo.position", m), _ && i("ICBM", _), d && U(d);
231
- const l = {
232
- ...f
253
+ description: a,
254
+ keywords: d,
255
+ author: u,
256
+ robots: w,
257
+ language: E,
258
+ viewport: v,
259
+ generator: A,
260
+ revisitAfter: b,
261
+ rating: j,
262
+ distribution: S,
263
+ copyright: T,
264
+ themeColor: N,
265
+ referrer: O,
266
+ formatDetection: _,
267
+ mobileWebAppCapable: D,
268
+ appleMobileWebAppCapable: I,
269
+ geoRegion: C,
270
+ geoPlacename: m,
271
+ geoPosition: p,
272
+ icbm: q,
273
+ canonical: g,
274
+ ogImage: h,
275
+ ogType: B,
276
+ ogUrl: G,
277
+ ogTitle: L,
278
+ ogDescription: $,
279
+ ogSiteName: x,
280
+ ogLocale: J,
281
+ twitterCard: M,
282
+ twitterSite: H,
283
+ twitterCreator: P,
284
+ twitterTitle: R,
285
+ twitterDescription: W,
286
+ twitterImage: F,
287
+ twitterImageAlt: V,
288
+ jsonLd: X,
289
+ customMeta: K,
290
+ openGraph: Y,
291
+ twitter: z,
292
+ googleAnalyticsId: Z,
293
+ googleTagManagerId: s,
294
+ customScripts: c
295
+ } = i;
296
+ r && ne(r), a && n("description", a);
297
+ const Q = se(d);
298
+ Q && n("keywords", Q), u && n("author", u), w && n("robots", w), E && (n("language", E), n("content-language", E)), v && n("viewport", v), A && n("generator", A), b && n("revisit-after", b), j && n("rating", j), S && n("distribution", S), T && n("copyright", T), N && n("theme-color", N), O && n("referrer", O), _ && n("format-detection", _), D && n("mobile-web-app-capable", D), I && n("apple-mobile-web-app-capable", I), C && n("geo.region", C), m && n("geo.placename", m), p && n("geo.position", p), q && n("ICBM", q), g && re(g);
299
+ const o = {
300
+ ...Y
233
301
  };
234
- (w || r) && (l.title = w || r), (x || c) && (l.description = x || c), T && (l.type = T), ($ || d) && (l.url = $ || d), p && (l.image = p), H && (l.siteName = H), L && (l.locale = L), Object.keys(l).length > 0 && k(l);
235
- const s = {
236
- ...o
302
+ (L || r) && (o.title = L || r), ($ || a) && (o.description = $ || a), B && (o.type = B), (G || g) && (o.url = G || g), h && (o.image = h), x && (o.siteName = x), J && (o.locale = J), Object.keys(o).length > 0 && ae(o);
303
+ const f = {
304
+ ...z
237
305
  };
238
- W && (s.card = W), M && (s.site = M), G && (s.creator = G), (I || r) && (s.title = I || r), (K || c) && (s.description = K || c), (z || p) && (s.image = z || p), Q && (s.imageAlt = Q), Object.keys(s).length > 0 && ee(s), X && te(X), V && ie(V, P);
239
- }, []), t = Z(() => {
240
- fe(), oe(P);
306
+ M && (f.card = M), H && (f.site = H), P && (f.creator = P), (R || r) && (f.title = R || r), (W || a) && (f.description = W || a), (F || h) && (f.image = F || h), V && (f.imageAlt = V), Object.keys(f).length > 0 && ce(f), K && oe(K), X && fe(X, ie), Z && le(Z), s && de(s), c && Array.isArray(c) && c.forEach((U) => {
307
+ ue(U);
308
+ });
309
+ }, []), t = te(() => {
310
+ ge(), he(ie);
241
311
  }, []);
242
312
  return {
243
313
  updateSeo: e,
@@ -245,7 +315,7 @@ function se() {
245
315
  };
246
316
  }
247
317
  export {
248
- le as Seo,
249
- se as useSeo
318
+ we as Seo,
319
+ ve as useSeo
250
320
  };
251
321
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils.ts","../src/Seo.tsx","../src/useSeo.ts"],"sourcesContent":["import type { CustomMeta, JsonLd, OpenGraphMeta, TwitterCardMeta } from './types';\r\n\r\n/**\r\n * Get or create a meta tag element\r\n */\r\nfunction getOrCreateMetaTag(attribute: 'name' | 'property', value: string): HTMLMetaElement {\r\n const selector = `meta[${attribute}=\"${value}\"]`;\r\n let element = document.querySelector<HTMLMetaElement>(selector);\r\n\r\n if (!element) {\r\n element = document.createElement('meta');\r\n element.setAttribute(attribute, value);\r\n document.head.appendChild(element);\r\n }\r\n\r\n return element;\r\n}\r\n\r\n/**\r\n * Set a meta tag by name\r\n */\r\nexport function setMetaTag(name: string, content: string): void {\r\n if (!content) return;\r\n\r\n const element = getOrCreateMetaTag('name', name);\r\n element.setAttribute('content', content);\r\n}\r\n\r\n/**\r\n * Set a meta tag by property (for Open Graph)\r\n */\r\nexport function setMetaProperty(property: string, content: string | number): void {\r\n if (content === undefined || content === null || content === '') return;\r\n\r\n const element = getOrCreateMetaTag('property', property);\r\n element.setAttribute('content', String(content));\r\n}\r\n\r\n/**\r\n * Set the page title\r\n */\r\nexport function setTitle(title: string): void {\r\n if (!title) return;\r\n document.title = title;\r\n}\r\n\r\n/**\r\n * Set canonical URL\r\n */\r\nexport function setCanonical(url: string): void {\r\n if (!url) return;\r\n\r\n let link = document.querySelector<HTMLLinkElement>('link[rel=\"canonical\"]');\r\n if (!link) {\r\n link = document.createElement('link');\r\n link.setAttribute('rel', 'canonical');\r\n document.head.appendChild(link);\r\n }\r\n link.setAttribute('href', url);\r\n}\r\n\r\n/**\r\n * Remove canonical URL\r\n */\r\nexport function removeCanonical(): void {\r\n const link = document.querySelector<HTMLLinkElement>('link[rel=\"canonical\"]');\r\n if (link) {\r\n link.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Set Open Graph meta tags\r\n */\r\nexport function setOpenGraphTags(og: OpenGraphMeta): void {\r\n if (!og) return;\r\n\r\n // Standard Open Graph properties\r\n if (og.title) setMetaProperty('og:title', og.title);\r\n if (og.description) setMetaProperty('og:description', og.description);\r\n if (og.type) setMetaProperty('og:type', og.type);\r\n if (og.url) setMetaProperty('og:url', og.url);\r\n if (og.image) setMetaProperty('og:image', og.image);\r\n if (og.imageWidth) setMetaProperty('og:image:width', og.imageWidth);\r\n if (og.imageHeight) setMetaProperty('og:image:height', og.imageHeight);\r\n if (og.imageAlt) setMetaProperty('og:image:alt', og.imageAlt);\r\n if (og.siteName) setMetaProperty('og:site_name', og.siteName);\r\n if (og.locale) setMetaProperty('og:locale', og.locale);\r\n\r\n // Handle additional custom og:* properties\r\n Object.keys(og).forEach((key) => {\r\n if (key.startsWith('og:') && key !== 'og:title' && key !== 'og:description' && \r\n key !== 'og:type' && key !== 'og:url' && key !== 'og:image' && \r\n key !== 'og:imageWidth' && key !== 'og:imageHeight' && \r\n key !== 'og:imageAlt' && key !== 'og:siteName' && key !== 'og:locale') {\r\n const value = og[key as keyof OpenGraphMeta];\r\n if (value !== undefined && value !== null && value !== '') {\r\n setMetaProperty(key, value as string | number);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Set Twitter Card meta tags\r\n */\r\nexport function setTwitterCardTags(twitter: TwitterCardMeta): void {\r\n if (!twitter) return;\r\n\r\n if (twitter.card) setMetaTag('twitter:card', twitter.card);\r\n if (twitter.site) setMetaTag('twitter:site', twitter.site);\r\n if (twitter.creator) setMetaTag('twitter:creator', twitter.creator);\r\n if (twitter.title) setMetaTag('twitter:title', twitter.title);\r\n if (twitter.description) setMetaTag('twitter:description', twitter.description);\r\n if (twitter.image) setMetaTag('twitter:image', twitter.image);\r\n if (twitter.imageAlt) setMetaTag('twitter:image:alt', twitter.imageAlt);\r\n\r\n // Handle additional custom twitter:* properties\r\n Object.keys(twitter).forEach((key) => {\r\n if (key.startsWith('twitter:') && key !== 'twitter:card' && key !== 'twitter:site' && \r\n key !== 'twitter:creator' && key !== 'twitter:title' && \r\n key !== 'twitter:description' && key !== 'twitter:image' && \r\n key !== 'twitter:imageAlt') {\r\n const value = twitter[key as keyof TwitterCardMeta];\r\n if (value !== undefined && value !== null && value !== '') {\r\n setMetaTag(key, String(value));\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Set custom meta tags\r\n */\r\nexport function setCustomMetaTags(customMeta: CustomMeta[]): void {\r\n if (!customMeta || !Array.isArray(customMeta)) return;\r\n\r\n customMeta.forEach((meta) => {\r\n if (!meta.content) return;\r\n\r\n let element: HTMLMetaElement | null = null;\r\n\r\n if (meta.name) {\r\n element = getOrCreateMetaTag('name', meta.name);\r\n } else if (meta.property) {\r\n element = getOrCreateMetaTag('property', meta.property);\r\n } else if (meta.httpEquiv) {\r\n const selector = `meta[http-equiv=\"${meta.httpEquiv}\"]`;\r\n element = document.querySelector<HTMLMetaElement>(selector);\r\n if (!element) {\r\n element = document.createElement('meta');\r\n element.setAttribute('http-equiv', meta.httpEquiv);\r\n document.head.appendChild(element);\r\n }\r\n } else if (meta.charset) {\r\n let charsetElement = document.querySelector<HTMLMetaElement>('meta[charset]');\r\n if (!charsetElement) {\r\n charsetElement = document.createElement('meta');\r\n charsetElement.setAttribute('charset', meta.charset);\r\n document.head.insertBefore(charsetElement, document.head.firstChild);\r\n }\r\n return;\r\n }\r\n\r\n if (element) {\r\n element.setAttribute('content', meta.content);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Inject JSON-LD structured data\r\n */\r\nexport function injectJsonLd(data: JsonLd, id?: string): () => void {\r\n const script = document.createElement('script');\r\n script.type = 'application/ld+json';\r\n if (id) {\r\n script.id = id;\r\n // Remove existing script with same id\r\n const existing = document.getElementById(id);\r\n if (existing) {\r\n existing.remove();\r\n }\r\n }\r\n script.textContent = JSON.stringify(data);\r\n document.head.appendChild(script);\r\n\r\n // Return cleanup function\r\n return () => {\r\n script.remove();\r\n };\r\n}\r\n\r\n/**\r\n * Remove JSON-LD script by id\r\n */\r\nexport function removeJsonLd(id: string): void {\r\n const script = document.getElementById(id);\r\n if (script && script.getAttribute('type') === 'application/ld+json') {\r\n script.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Format keywords as string\r\n */\r\nexport function formatKeywords(keywords: string | string[] | undefined): string {\r\n if (!keywords) return '';\r\n if (Array.isArray(keywords)) {\r\n return keywords.join(', ');\r\n }\r\n return keywords;\r\n}\r\n\r\n","import { useEffect } from 'react';\r\nimport type { SeoProps } from './types';\r\nimport {\r\n setTitle,\r\n setMetaTag,\r\n setCanonical,\r\n setOpenGraphTags,\r\n setTwitterCardTags,\r\n setCustomMetaTags,\r\n injectJsonLd,\r\n formatKeywords,\r\n} from './utils';\r\n\r\nconst JSON_LD_ID = 'react-client-seo-jsonld';\r\n\r\n/**\r\n * SEO Component\r\n * \r\n * Renders and updates SEO meta tags in the document head.\r\n * Returns null (no UI rendering).\r\n * \r\n * @example\r\n * ```tsx\r\n * <Seo\r\n * title=\"My Page Title\"\r\n * description=\"Page description\"\r\n * keywords={['react', 'seo']}\r\n * canonical=\"https://example.com/page\"\r\n * ogImage=\"https://example.com/image.jpg\"\r\n * jsonLd={{ \"@context\": \"https://schema.org\", \"@type\": \"WebPage\" }}\r\n * />\r\n * ```\r\n */\r\nexport function Seo({\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n}: SeoProps) {\r\n useEffect(() => {\r\n // Set title\r\n if (title) {\r\n setTitle(title);\r\n }\r\n\r\n // Set description\r\n if (description) {\r\n setMetaTag('description', description);\r\n }\r\n\r\n // Set keywords\r\n const keywordsStr = formatKeywords(keywords);\r\n if (keywordsStr) {\r\n setMetaTag('keywords', keywordsStr);\r\n }\r\n\r\n // Set author\r\n if (author) {\r\n setMetaTag('author', author);\r\n }\r\n\r\n // Set robots\r\n if (robots) {\r\n setMetaTag('robots', robots);\r\n }\r\n\r\n // Set language\r\n if (language) {\r\n setMetaTag('language', language);\r\n setMetaTag('content-language', language);\r\n }\r\n\r\n // Set viewport\r\n if (viewport) {\r\n setMetaTag('viewport', viewport);\r\n }\r\n\r\n // Set generator\r\n if (generator) {\r\n setMetaTag('generator', generator);\r\n }\r\n\r\n // Set revisit-after\r\n if (revisitAfter) {\r\n setMetaTag('revisit-after', revisitAfter);\r\n }\r\n\r\n // Set rating\r\n if (rating) {\r\n setMetaTag('rating', rating);\r\n }\r\n\r\n // Set distribution\r\n if (distribution) {\r\n setMetaTag('distribution', distribution);\r\n }\r\n\r\n // Set copyright\r\n if (copyright) {\r\n setMetaTag('copyright', copyright);\r\n }\r\n\r\n // Set theme-color\r\n if (themeColor) {\r\n setMetaTag('theme-color', themeColor);\r\n }\r\n\r\n // Set referrer\r\n if (referrer) {\r\n setMetaTag('referrer', referrer);\r\n }\r\n\r\n // Set format-detection\r\n if (formatDetection) {\r\n setMetaTag('format-detection', formatDetection);\r\n }\r\n\r\n // Set mobile-web-app-capable\r\n if (mobileWebAppCapable) {\r\n setMetaTag('mobile-web-app-capable', mobileWebAppCapable);\r\n }\r\n\r\n // Set apple-mobile-web-app-capable\r\n if (appleMobileWebAppCapable) {\r\n setMetaTag('apple-mobile-web-app-capable', appleMobileWebAppCapable);\r\n }\r\n\r\n // Set geo tags\r\n if (geoRegion) {\r\n setMetaTag('geo.region', geoRegion);\r\n }\r\n if (geoPlacename) {\r\n setMetaTag('geo.placename', geoPlacename);\r\n }\r\n if (geoPosition) {\r\n setMetaTag('geo.position', geoPosition);\r\n }\r\n if (icbm) {\r\n setMetaTag('ICBM', icbm);\r\n }\r\n\r\n // Set canonical URL\r\n if (canonical) {\r\n setCanonical(canonical);\r\n }\r\n\r\n // Build Open Graph object\r\n const ogData: any = {\r\n ...openGraph,\r\n };\r\n\r\n if (ogTitle || title) {\r\n ogData.title = ogTitle || title;\r\n }\r\n if (ogDescription || description) {\r\n ogData.description = ogDescription || description;\r\n }\r\n if (ogType) {\r\n ogData.type = ogType;\r\n }\r\n if (ogUrl || canonical) {\r\n ogData.url = ogUrl || canonical;\r\n }\r\n if (ogImage) {\r\n ogData.image = ogImage;\r\n }\r\n if (ogSiteName) {\r\n ogData.siteName = ogSiteName;\r\n }\r\n if (ogLocale) {\r\n ogData.locale = ogLocale;\r\n }\r\n\r\n if (Object.keys(ogData).length > 0) {\r\n setOpenGraphTags(ogData);\r\n }\r\n\r\n // Build Twitter Card object\r\n const twitterData: any = {\r\n ...twitter,\r\n };\r\n\r\n if (twitterCard) {\r\n twitterData.card = twitterCard;\r\n }\r\n if (twitterSite) {\r\n twitterData.site = twitterSite;\r\n }\r\n if (twitterCreator) {\r\n twitterData.creator = twitterCreator;\r\n }\r\n if (twitterTitle || title) {\r\n twitterData.title = twitterTitle || title;\r\n }\r\n if (twitterDescription || description) {\r\n twitterData.description = twitterDescription || description;\r\n }\r\n if (twitterImage || ogImage) {\r\n twitterData.image = twitterImage || ogImage;\r\n }\r\n if (twitterImageAlt) {\r\n twitterData.imageAlt = twitterImageAlt;\r\n }\r\n\r\n if (Object.keys(twitterData).length > 0) {\r\n setTwitterCardTags(twitterData);\r\n }\r\n\r\n // Set custom meta tags\r\n if (customMeta) {\r\n setCustomMetaTags(customMeta);\r\n }\r\n\r\n // Inject JSON-LD\r\n let cleanupJsonLd: (() => void) | null = null;\r\n if (jsonLd) {\r\n cleanupJsonLd = injectJsonLd(jsonLd, JSON_LD_ID);\r\n }\r\n\r\n // Cleanup function\r\n return () => {\r\n if (cleanupJsonLd) {\r\n cleanupJsonLd();\r\n }\r\n };\r\n }, [\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n ]);\r\n\r\n return null;\r\n}\r\n\r\n","import { useCallback } from 'react';\r\nimport type { SeoProps, UseSeoReturn } from './types';\r\nimport {\r\n setTitle,\r\n setMetaTag,\r\n setCanonical,\r\n setOpenGraphTags,\r\n setTwitterCardTags,\r\n setCustomMetaTags,\r\n injectJsonLd,\r\n formatKeywords,\r\n removeCanonical,\r\n removeJsonLd,\r\n} from './utils';\r\n\r\nconst JSON_LD_ID = 'react-client-seo-jsonld';\r\n\r\n/**\r\n * useSeo Hook\r\n * \r\n * Hook-based API for managing SEO meta tags.\r\n * \r\n * @example\r\n * ```tsx\r\n * function MyComponent() {\r\n * const { updateSeo } = useSeo();\r\n * \r\n * useEffect(() => {\r\n * updateSeo({\r\n * title: 'My Page',\r\n * description: 'Page description',\r\n * });\r\n * }, []);\r\n * \r\n * return <div>Content</div>;\r\n * }\r\n * ```\r\n */\r\nexport function useSeo(): UseSeoReturn {\r\n const updateSeo = useCallback((props: SeoProps) => {\r\n const {\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n } = props;\r\n\r\n // Set title\r\n if (title) {\r\n setTitle(title);\r\n }\r\n\r\n // Set description\r\n if (description) {\r\n setMetaTag('description', description);\r\n }\r\n\r\n // Set keywords\r\n const keywordsStr = formatKeywords(keywords);\r\n if (keywordsStr) {\r\n setMetaTag('keywords', keywordsStr);\r\n }\r\n\r\n // Set author\r\n if (author) {\r\n setMetaTag('author', author);\r\n }\r\n\r\n // Set robots\r\n if (robots) {\r\n setMetaTag('robots', robots);\r\n }\r\n\r\n // Set language\r\n if (language) {\r\n setMetaTag('language', language);\r\n setMetaTag('content-language', language);\r\n }\r\n\r\n // Set viewport\r\n if (viewport) {\r\n setMetaTag('viewport', viewport);\r\n }\r\n\r\n // Set generator\r\n if (generator) {\r\n setMetaTag('generator', generator);\r\n }\r\n\r\n // Set revisit-after\r\n if (revisitAfter) {\r\n setMetaTag('revisit-after', revisitAfter);\r\n }\r\n\r\n // Set rating\r\n if (rating) {\r\n setMetaTag('rating', rating);\r\n }\r\n\r\n // Set distribution\r\n if (distribution) {\r\n setMetaTag('distribution', distribution);\r\n }\r\n\r\n // Set copyright\r\n if (copyright) {\r\n setMetaTag('copyright', copyright);\r\n }\r\n\r\n // Set theme-color\r\n if (themeColor) {\r\n setMetaTag('theme-color', themeColor);\r\n }\r\n\r\n // Set referrer\r\n if (referrer) {\r\n setMetaTag('referrer', referrer);\r\n }\r\n\r\n // Set format-detection\r\n if (formatDetection) {\r\n setMetaTag('format-detection', formatDetection);\r\n }\r\n\r\n // Set mobile-web-app-capable\r\n if (mobileWebAppCapable) {\r\n setMetaTag('mobile-web-app-capable', mobileWebAppCapable);\r\n }\r\n\r\n // Set apple-mobile-web-app-capable\r\n if (appleMobileWebAppCapable) {\r\n setMetaTag('apple-mobile-web-app-capable', appleMobileWebAppCapable);\r\n }\r\n\r\n // Set geo tags\r\n if (geoRegion) {\r\n setMetaTag('geo.region', geoRegion);\r\n }\r\n if (geoPlacename) {\r\n setMetaTag('geo.placename', geoPlacename);\r\n }\r\n if (geoPosition) {\r\n setMetaTag('geo.position', geoPosition);\r\n }\r\n if (icbm) {\r\n setMetaTag('ICBM', icbm);\r\n }\r\n\r\n // Set canonical URL\r\n if (canonical) {\r\n setCanonical(canonical);\r\n }\r\n\r\n // Build Open Graph object\r\n const ogData: any = {\r\n ...openGraph,\r\n };\r\n\r\n if (ogTitle || title) {\r\n ogData.title = ogTitle || title;\r\n }\r\n if (ogDescription || description) {\r\n ogData.description = ogDescription || description;\r\n }\r\n if (ogType) {\r\n ogData.type = ogType;\r\n }\r\n if (ogUrl || canonical) {\r\n ogData.url = ogUrl || canonical;\r\n }\r\n if (ogImage) {\r\n ogData.image = ogImage;\r\n }\r\n if (ogSiteName) {\r\n ogData.siteName = ogSiteName;\r\n }\r\n if (ogLocale) {\r\n ogData.locale = ogLocale;\r\n }\r\n\r\n if (Object.keys(ogData).length > 0) {\r\n setOpenGraphTags(ogData);\r\n }\r\n\r\n // Build Twitter Card object\r\n const twitterData: any = {\r\n ...twitter,\r\n };\r\n\r\n if (twitterCard) {\r\n twitterData.card = twitterCard;\r\n }\r\n if (twitterSite) {\r\n twitterData.site = twitterSite;\r\n }\r\n if (twitterCreator) {\r\n twitterData.creator = twitterCreator;\r\n }\r\n if (twitterTitle || title) {\r\n twitterData.title = twitterTitle || title;\r\n }\r\n if (twitterDescription || description) {\r\n twitterData.description = twitterDescription || description;\r\n }\r\n if (twitterImage || ogImage) {\r\n twitterData.image = twitterImage || ogImage;\r\n }\r\n if (twitterImageAlt) {\r\n twitterData.imageAlt = twitterImageAlt;\r\n }\r\n\r\n if (Object.keys(twitterData).length > 0) {\r\n setTwitterCardTags(twitterData);\r\n }\r\n\r\n // Set custom meta tags\r\n if (customMeta) {\r\n setCustomMetaTags(customMeta);\r\n }\r\n\r\n // Inject JSON-LD\r\n if (jsonLd) {\r\n injectJsonLd(jsonLd, JSON_LD_ID);\r\n }\r\n }, []);\r\n\r\n const clearSeo = useCallback(() => {\r\n // Note: We don't clear title, description, keywords as they might be set by other means\r\n // Only clear what we manage\r\n removeCanonical();\r\n removeJsonLd(JSON_LD_ID);\r\n }, []);\r\n\r\n return {\r\n updateSeo,\r\n clearSeo,\r\n };\r\n}\r\n\r\n"],"names":["getOrCreateMetaTag","attribute","value","selector","element","setMetaTag","name","content","setMetaProperty","property","setTitle","title","setCanonical","url","link","removeCanonical","setOpenGraphTags","og","key","setTwitterCardTags","twitter","setCustomMetaTags","customMeta","meta","charsetElement","injectJsonLd","data","id","script","existing","removeJsonLd","formatKeywords","keywords","JSON_LD_ID","Seo","description","author","robots","language","viewport","generator","revisitAfter","rating","distribution","copyright","themeColor","referrer","formatDetection","mobileWebAppCapable","appleMobileWebAppCapable","geoRegion","geoPlacename","geoPosition","icbm","canonical","ogImage","ogType","ogUrl","ogTitle","ogDescription","ogSiteName","ogLocale","twitterCard","twitterSite","twitterCreator","twitterTitle","twitterDescription","twitterImage","twitterImageAlt","jsonLd","openGraph","useEffect","keywordsStr","ogData","twitterData","cleanupJsonLd","useSeo","updateSeo","useCallback","props","clearSeo"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils.ts","../src/Seo.tsx","../src/useSeo.ts"],"sourcesContent":["import type { CustomMeta, CustomScript, JsonLd, OpenGraphMeta, TwitterCardMeta } from './types';\r\n\r\n/**\r\n * Get or create a meta tag element\r\n */\r\nfunction getOrCreateMetaTag(attribute: 'name' | 'property', value: string): HTMLMetaElement {\r\n const selector = `meta[${attribute}=\"${value}\"]`;\r\n let element = document.querySelector<HTMLMetaElement>(selector);\r\n\r\n if (!element) {\r\n element = document.createElement('meta');\r\n element.setAttribute(attribute, value);\r\n document.head.appendChild(element);\r\n }\r\n\r\n return element;\r\n}\r\n\r\n/**\r\n * Set a meta tag by name\r\n */\r\nexport function setMetaTag(name: string, content: string): void {\r\n if (!content) return;\r\n\r\n const element = getOrCreateMetaTag('name', name);\r\n element.setAttribute('content', content);\r\n}\r\n\r\n/**\r\n * Set a meta tag by property (for Open Graph)\r\n */\r\nexport function setMetaProperty(property: string, content: string | number): void {\r\n if (content === undefined || content === null || content === '') return;\r\n\r\n const element = getOrCreateMetaTag('property', property);\r\n element.setAttribute('content', String(content));\r\n}\r\n\r\n/**\r\n * Set the page title\r\n */\r\nexport function setTitle(title: string): void {\r\n if (!title) return;\r\n document.title = title;\r\n}\r\n\r\n/**\r\n * Set canonical URL\r\n */\r\nexport function setCanonical(url: string): void {\r\n if (!url) return;\r\n\r\n let link = document.querySelector<HTMLLinkElement>('link[rel=\"canonical\"]');\r\n if (!link) {\r\n link = document.createElement('link');\r\n link.setAttribute('rel', 'canonical');\r\n document.head.appendChild(link);\r\n }\r\n link.setAttribute('href', url);\r\n}\r\n\r\n/**\r\n * Remove canonical URL\r\n */\r\nexport function removeCanonical(): void {\r\n const link = document.querySelector<HTMLLinkElement>('link[rel=\"canonical\"]');\r\n if (link) {\r\n link.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Set Open Graph meta tags\r\n */\r\nexport function setOpenGraphTags(og: OpenGraphMeta): void {\r\n if (!og) return;\r\n\r\n // Standard Open Graph properties\r\n if (og.title) setMetaProperty('og:title', og.title);\r\n if (og.description) setMetaProperty('og:description', og.description);\r\n if (og.type) setMetaProperty('og:type', og.type);\r\n if (og.url) setMetaProperty('og:url', og.url);\r\n if (og.image) setMetaProperty('og:image', og.image);\r\n if (og.imageWidth) setMetaProperty('og:image:width', og.imageWidth);\r\n if (og.imageHeight) setMetaProperty('og:image:height', og.imageHeight);\r\n if (og.imageAlt) setMetaProperty('og:image:alt', og.imageAlt);\r\n if (og.siteName) setMetaProperty('og:site_name', og.siteName);\r\n if (og.locale) setMetaProperty('og:locale', og.locale);\r\n\r\n // Handle additional custom og:* properties\r\n Object.keys(og).forEach((key) => {\r\n if (key.startsWith('og:') && key !== 'og:title' && key !== 'og:description' && \r\n key !== 'og:type' && key !== 'og:url' && key !== 'og:image' && \r\n key !== 'og:imageWidth' && key !== 'og:imageHeight' && \r\n key !== 'og:imageAlt' && key !== 'og:siteName' && key !== 'og:locale') {\r\n const value = og[key as keyof OpenGraphMeta];\r\n if (value !== undefined && value !== null && value !== '') {\r\n setMetaProperty(key, value as string | number);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Set Twitter Card meta tags\r\n */\r\nexport function setTwitterCardTags(twitter: TwitterCardMeta): void {\r\n if (!twitter) return;\r\n\r\n if (twitter.card) setMetaTag('twitter:card', twitter.card);\r\n if (twitter.site) setMetaTag('twitter:site', twitter.site);\r\n if (twitter.creator) setMetaTag('twitter:creator', twitter.creator);\r\n if (twitter.title) setMetaTag('twitter:title', twitter.title);\r\n if (twitter.description) setMetaTag('twitter:description', twitter.description);\r\n if (twitter.image) setMetaTag('twitter:image', twitter.image);\r\n if (twitter.imageAlt) setMetaTag('twitter:image:alt', twitter.imageAlt);\r\n\r\n // Handle additional custom twitter:* properties\r\n Object.keys(twitter).forEach((key) => {\r\n if (key.startsWith('twitter:') && key !== 'twitter:card' && key !== 'twitter:site' && \r\n key !== 'twitter:creator' && key !== 'twitter:title' && \r\n key !== 'twitter:description' && key !== 'twitter:image' && \r\n key !== 'twitter:imageAlt') {\r\n const value = twitter[key as keyof TwitterCardMeta];\r\n if (value !== undefined && value !== null && value !== '') {\r\n setMetaTag(key, String(value));\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Set custom meta tags\r\n */\r\nexport function setCustomMetaTags(customMeta: CustomMeta[]): void {\r\n if (!customMeta || !Array.isArray(customMeta)) return;\r\n\r\n customMeta.forEach((meta) => {\r\n if (!meta.content) return;\r\n\r\n let element: HTMLMetaElement | null = null;\r\n\r\n if (meta.name) {\r\n element = getOrCreateMetaTag('name', meta.name);\r\n } else if (meta.property) {\r\n element = getOrCreateMetaTag('property', meta.property);\r\n } else if (meta.httpEquiv) {\r\n const selector = `meta[http-equiv=\"${meta.httpEquiv}\"]`;\r\n element = document.querySelector<HTMLMetaElement>(selector);\r\n if (!element) {\r\n element = document.createElement('meta');\r\n element.setAttribute('http-equiv', meta.httpEquiv);\r\n document.head.appendChild(element);\r\n }\r\n } else if (meta.charset) {\r\n let charsetElement = document.querySelector<HTMLMetaElement>('meta[charset]');\r\n if (!charsetElement) {\r\n charsetElement = document.createElement('meta');\r\n charsetElement.setAttribute('charset', meta.charset);\r\n document.head.insertBefore(charsetElement, document.head.firstChild);\r\n }\r\n return;\r\n }\r\n\r\n if (element) {\r\n element.setAttribute('content', meta.content);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Inject JSON-LD structured data\r\n */\r\nexport function injectJsonLd(data: JsonLd, id?: string): () => void {\r\n const script = document.createElement('script');\r\n script.type = 'application/ld+json';\r\n if (id) {\r\n script.id = id;\r\n // Remove existing script with same id\r\n const existing = document.getElementById(id);\r\n if (existing) {\r\n existing.remove();\r\n }\r\n }\r\n script.textContent = JSON.stringify(data);\r\n document.head.appendChild(script);\r\n\r\n // Return cleanup function\r\n return () => {\r\n script.remove();\r\n };\r\n}\r\n\r\n/**\r\n * Remove JSON-LD script by id\r\n */\r\nexport function removeJsonLd(id: string): void {\r\n const script = document.getElementById(id);\r\n if (script && script.getAttribute('type') === 'application/ld+json') {\r\n script.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Format keywords as string\r\n */\r\nexport function formatKeywords(keywords: string | string[] | undefined): string {\r\n if (!keywords) return '';\r\n if (Array.isArray(keywords)) {\r\n return keywords.join(', ');\r\n }\r\n return keywords;\r\n}\r\n\r\n/**\r\n * Remove script by id\r\n */\r\nexport function removeScript(id: string): void {\r\n const script = document.getElementById(id);\r\n if (script && script.tagName === 'SCRIPT') {\r\n script.remove();\r\n }\r\n}\r\n\r\n/**\r\n * Inject Google Analytics script\r\n */\r\nexport function injectGoogleAnalytics(id: string): () => void {\r\n const GA_SCRIPT_ID = 'react-client-seo-ga';\r\n const GA_CONFIG_ID = 'react-client-seo-ga-config';\r\n\r\n // Remove existing scripts if present\r\n removeScript(GA_SCRIPT_ID);\r\n removeScript(GA_CONFIG_ID);\r\n\r\n // Inject gtag.js script\r\n const script = document.createElement('script');\r\n script.id = GA_SCRIPT_ID;\r\n script.async = true;\r\n script.src = `https://www.googletagmanager.com/gtag/js?id=${id}`;\r\n document.head.appendChild(script);\r\n\r\n // Inject gtag config script\r\n const configScript = document.createElement('script');\r\n configScript.id = GA_CONFIG_ID;\r\n configScript.textContent = `\r\n window.dataLayer = window.dataLayer || [];\r\n function gtag(){dataLayer.push(arguments);}\r\n gtag('js', new Date());\r\n gtag('config', '${id}');\r\n `;\r\n document.head.appendChild(configScript);\r\n\r\n // Return cleanup function\r\n return () => {\r\n removeScript(GA_SCRIPT_ID);\r\n removeScript(GA_CONFIG_ID);\r\n };\r\n}\r\n\r\n/**\r\n * Inject Google Tag Manager script\r\n */\r\nexport function injectGoogleTagManager(id: string): () => void {\r\n const GTM_SCRIPT_ID = 'react-client-seo-gtm';\r\n const GTM_NOSCRIPT_ID = 'react-client-seo-gtm-noscript';\r\n\r\n // Remove existing scripts if present\r\n removeScript(GTM_SCRIPT_ID);\r\n const existingNoscript = document.getElementById(GTM_NOSCRIPT_ID);\r\n if (existingNoscript) {\r\n existingNoscript.remove();\r\n }\r\n\r\n // Inject GTM script\r\n const script = document.createElement('script');\r\n script.id = GTM_SCRIPT_ID;\r\n script.textContent = `\r\n (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\r\n new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\r\n j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=\r\n 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\r\n })(window,document,'script','dataLayer','${id}');\r\n `;\r\n document.head.appendChild(script);\r\n\r\n // Inject GTM noscript (in body, but we'll add it to head with a marker)\r\n // Note: GTM noscript should ideally be in body, but for client-side rendering\r\n // we'll inject it and let the user know they may need to add it to body manually\r\n const noscript = document.createElement('noscript');\r\n noscript.id = GTM_NOSCRIPT_ID;\r\n noscript.innerHTML = `<iframe src=\"https://www.googletagmanager.com/ns.html?id=${id}\" height=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"></iframe>`;\r\n document.head.appendChild(noscript);\r\n\r\n // Return cleanup function\r\n return () => {\r\n removeScript(GTM_SCRIPT_ID);\r\n const noscriptEl = document.getElementById(GTM_NOSCRIPT_ID);\r\n if (noscriptEl) {\r\n noscriptEl.remove();\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Inject custom script\r\n */\r\nexport function injectCustomScript(scriptConfig: CustomScript): () => void {\r\n if (!scriptConfig.src && !scriptConfig.content) {\r\n console.warn('CustomScript must have either src or content');\r\n return () => {};\r\n }\r\n\r\n const scriptId = scriptConfig.id || `react-client-seo-custom-${Date.now()}`;\r\n\r\n // Remove existing script if present\r\n if (scriptConfig.id) {\r\n removeScript(scriptConfig.id);\r\n }\r\n\r\n const script = document.createElement('script');\r\n script.id = scriptId;\r\n\r\n if (scriptConfig.src) {\r\n script.src = scriptConfig.src;\r\n }\r\n\r\n if (scriptConfig.content) {\r\n script.textContent = scriptConfig.content;\r\n }\r\n\r\n // Set script attributes\r\n if (scriptConfig.type) {\r\n script.type = scriptConfig.type;\r\n } else {\r\n script.type = 'text/javascript';\r\n }\r\n\r\n if (scriptConfig.strategy === 'async' || scriptConfig.async) {\r\n script.async = true;\r\n }\r\n\r\n if (scriptConfig.strategy === 'defer' || scriptConfig.defer) {\r\n script.defer = true;\r\n }\r\n\r\n document.head.appendChild(script);\r\n\r\n // Return cleanup function\r\n return () => {\r\n removeScript(scriptId);\r\n };\r\n}\r\n","import { useEffect } from 'react';\r\nimport type { SeoProps } from './types';\r\nimport {\r\n setTitle,\r\n setMetaTag,\r\n setCanonical,\r\n setOpenGraphTags,\r\n setTwitterCardTags,\r\n setCustomMetaTags,\r\n injectJsonLd,\r\n formatKeywords,\r\n injectGoogleAnalytics,\r\n injectGoogleTagManager,\r\n injectCustomScript,\r\n} from './utils';\r\n\r\nconst JSON_LD_ID = 'react-client-seo-jsonld';\r\n\r\n/**\r\n * SEO Component\r\n * \r\n * Renders and updates SEO meta tags in the document head.\r\n * Returns null (no UI rendering).\r\n * \r\n * @example\r\n * ```tsx\r\n * <Seo\r\n * title=\"My Page Title\"\r\n * description=\"Page description\"\r\n * keywords={['react', 'seo']}\r\n * canonical=\"https://example.com/page\"\r\n * ogImage=\"https://example.com/image.jpg\"\r\n * jsonLd={{ \"@context\": \"https://schema.org\", \"@type\": \"WebPage\" }}\r\n * />\r\n * ```\r\n */\r\nexport function Seo({\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n googleAnalyticsId,\r\n googleTagManagerId,\r\n customScripts,\r\n}: SeoProps) {\r\n useEffect(() => {\r\n // Set title\r\n if (title) {\r\n setTitle(title);\r\n }\r\n\r\n // Set description\r\n if (description) {\r\n setMetaTag('description', description);\r\n }\r\n\r\n // Set keywords\r\n const keywordsStr = formatKeywords(keywords);\r\n if (keywordsStr) {\r\n setMetaTag('keywords', keywordsStr);\r\n }\r\n\r\n // Set author\r\n if (author) {\r\n setMetaTag('author', author);\r\n }\r\n\r\n // Set robots\r\n if (robots) {\r\n setMetaTag('robots', robots);\r\n }\r\n\r\n // Set language\r\n if (language) {\r\n setMetaTag('language', language);\r\n setMetaTag('content-language', language);\r\n }\r\n\r\n // Set viewport\r\n if (viewport) {\r\n setMetaTag('viewport', viewport);\r\n }\r\n\r\n // Set generator\r\n if (generator) {\r\n setMetaTag('generator', generator);\r\n }\r\n\r\n // Set revisit-after\r\n if (revisitAfter) {\r\n setMetaTag('revisit-after', revisitAfter);\r\n }\r\n\r\n // Set rating\r\n if (rating) {\r\n setMetaTag('rating', rating);\r\n }\r\n\r\n // Set distribution\r\n if (distribution) {\r\n setMetaTag('distribution', distribution);\r\n }\r\n\r\n // Set copyright\r\n if (copyright) {\r\n setMetaTag('copyright', copyright);\r\n }\r\n\r\n // Set theme-color\r\n if (themeColor) {\r\n setMetaTag('theme-color', themeColor);\r\n }\r\n\r\n // Set referrer\r\n if (referrer) {\r\n setMetaTag('referrer', referrer);\r\n }\r\n\r\n // Set format-detection\r\n if (formatDetection) {\r\n setMetaTag('format-detection', formatDetection);\r\n }\r\n\r\n // Set mobile-web-app-capable\r\n if (mobileWebAppCapable) {\r\n setMetaTag('mobile-web-app-capable', mobileWebAppCapable);\r\n }\r\n\r\n // Set apple-mobile-web-app-capable\r\n if (appleMobileWebAppCapable) {\r\n setMetaTag('apple-mobile-web-app-capable', appleMobileWebAppCapable);\r\n }\r\n\r\n // Set geo tags\r\n if (geoRegion) {\r\n setMetaTag('geo.region', geoRegion);\r\n }\r\n if (geoPlacename) {\r\n setMetaTag('geo.placename', geoPlacename);\r\n }\r\n if (geoPosition) {\r\n setMetaTag('geo.position', geoPosition);\r\n }\r\n if (icbm) {\r\n setMetaTag('ICBM', icbm);\r\n }\r\n\r\n // Set canonical URL\r\n if (canonical) {\r\n setCanonical(canonical);\r\n }\r\n\r\n // Build Open Graph object\r\n const ogData: any = {\r\n ...openGraph,\r\n };\r\n\r\n if (ogTitle || title) {\r\n ogData.title = ogTitle || title;\r\n }\r\n if (ogDescription || description) {\r\n ogData.description = ogDescription || description;\r\n }\r\n if (ogType) {\r\n ogData.type = ogType;\r\n }\r\n if (ogUrl || canonical) {\r\n ogData.url = ogUrl || canonical;\r\n }\r\n if (ogImage) {\r\n ogData.image = ogImage;\r\n }\r\n if (ogSiteName) {\r\n ogData.siteName = ogSiteName;\r\n }\r\n if (ogLocale) {\r\n ogData.locale = ogLocale;\r\n }\r\n\r\n if (Object.keys(ogData).length > 0) {\r\n setOpenGraphTags(ogData);\r\n }\r\n\r\n // Build Twitter Card object\r\n const twitterData: any = {\r\n ...twitter,\r\n };\r\n\r\n if (twitterCard) {\r\n twitterData.card = twitterCard;\r\n }\r\n if (twitterSite) {\r\n twitterData.site = twitterSite;\r\n }\r\n if (twitterCreator) {\r\n twitterData.creator = twitterCreator;\r\n }\r\n if (twitterTitle || title) {\r\n twitterData.title = twitterTitle || title;\r\n }\r\n if (twitterDescription || description) {\r\n twitterData.description = twitterDescription || description;\r\n }\r\n if (twitterImage || ogImage) {\r\n twitterData.image = twitterImage || ogImage;\r\n }\r\n if (twitterImageAlt) {\r\n twitterData.imageAlt = twitterImageAlt;\r\n }\r\n\r\n if (Object.keys(twitterData).length > 0) {\r\n setTwitterCardTags(twitterData);\r\n }\r\n\r\n // Set custom meta tags\r\n if (customMeta) {\r\n setCustomMetaTags(customMeta);\r\n }\r\n\r\n // Inject JSON-LD\r\n let cleanupJsonLd: (() => void) | null = null;\r\n if (jsonLd) {\r\n cleanupJsonLd = injectJsonLd(jsonLd, JSON_LD_ID);\r\n }\r\n\r\n // Inject Google Analytics\r\n let cleanupGA: (() => void) | null = null;\r\n if (googleAnalyticsId) {\r\n cleanupGA = injectGoogleAnalytics(googleAnalyticsId);\r\n }\r\n\r\n // Inject Google Tag Manager\r\n let cleanupGTM: (() => void) | null = null;\r\n if (googleTagManagerId) {\r\n cleanupGTM = injectGoogleTagManager(googleTagManagerId);\r\n }\r\n\r\n // Inject custom scripts\r\n const cleanupCustomScripts: (() => void)[] = [];\r\n if (customScripts && Array.isArray(customScripts)) {\r\n customScripts.forEach((scriptConfig) => {\r\n const cleanup = injectCustomScript(scriptConfig);\r\n cleanupCustomScripts.push(cleanup);\r\n });\r\n }\r\n\r\n // Cleanup function\r\n return () => {\r\n if (cleanupJsonLd) {\r\n cleanupJsonLd();\r\n }\r\n if (cleanupGA) {\r\n cleanupGA();\r\n }\r\n if (cleanupGTM) {\r\n cleanupGTM();\r\n }\r\n cleanupCustomScripts.forEach((cleanup) => cleanup());\r\n };\r\n }, [\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n googleAnalyticsId,\r\n googleTagManagerId,\r\n customScripts,\r\n ]);\r\n\r\n return null;\r\n}\r\n\r\n","import { useCallback } from 'react';\r\nimport type { SeoProps, UseSeoReturn } from './types';\r\nimport {\r\n setTitle,\r\n setMetaTag,\r\n setCanonical,\r\n setOpenGraphTags,\r\n setTwitterCardTags,\r\n setCustomMetaTags,\r\n injectJsonLd,\r\n formatKeywords,\r\n removeCanonical,\r\n removeJsonLd,\r\n injectGoogleAnalytics,\r\n injectGoogleTagManager,\r\n injectCustomScript,\r\n} from './utils';\r\n\r\nconst JSON_LD_ID = 'react-client-seo-jsonld';\r\n\r\n/**\r\n * useSeo Hook\r\n * \r\n * Hook-based API for managing SEO meta tags.\r\n * \r\n * @example\r\n * ```tsx\r\n * function MyComponent() {\r\n * const { updateSeo } = useSeo();\r\n * \r\n * useEffect(() => {\r\n * updateSeo({\r\n * title: 'My Page',\r\n * description: 'Page description',\r\n * });\r\n * }, []);\r\n * \r\n * return <div>Content</div>;\r\n * }\r\n * ```\r\n */\r\nexport function useSeo(): UseSeoReturn {\r\n const updateSeo = useCallback((props: SeoProps) => {\r\n const {\r\n title,\r\n description,\r\n keywords,\r\n author,\r\n robots,\r\n language,\r\n viewport,\r\n generator,\r\n revisitAfter,\r\n rating,\r\n distribution,\r\n copyright,\r\n themeColor,\r\n referrer,\r\n formatDetection,\r\n mobileWebAppCapable,\r\n appleMobileWebAppCapable,\r\n geoRegion,\r\n geoPlacename,\r\n geoPosition,\r\n icbm,\r\n canonical,\r\n ogImage,\r\n ogType,\r\n ogUrl,\r\n ogTitle,\r\n ogDescription,\r\n ogSiteName,\r\n ogLocale,\r\n twitterCard,\r\n twitterSite,\r\n twitterCreator,\r\n twitterTitle,\r\n twitterDescription,\r\n twitterImage,\r\n twitterImageAlt,\r\n jsonLd,\r\n customMeta,\r\n openGraph,\r\n twitter,\r\n googleAnalyticsId,\r\n googleTagManagerId,\r\n customScripts,\r\n } = props;\r\n\r\n // Set title\r\n if (title) {\r\n setTitle(title);\r\n }\r\n\r\n // Set description\r\n if (description) {\r\n setMetaTag('description', description);\r\n }\r\n\r\n // Set keywords\r\n const keywordsStr = formatKeywords(keywords);\r\n if (keywordsStr) {\r\n setMetaTag('keywords', keywordsStr);\r\n }\r\n\r\n // Set author\r\n if (author) {\r\n setMetaTag('author', author);\r\n }\r\n\r\n // Set robots\r\n if (robots) {\r\n setMetaTag('robots', robots);\r\n }\r\n\r\n // Set language\r\n if (language) {\r\n setMetaTag('language', language);\r\n setMetaTag('content-language', language);\r\n }\r\n\r\n // Set viewport\r\n if (viewport) {\r\n setMetaTag('viewport', viewport);\r\n }\r\n\r\n // Set generator\r\n if (generator) {\r\n setMetaTag('generator', generator);\r\n }\r\n\r\n // Set revisit-after\r\n if (revisitAfter) {\r\n setMetaTag('revisit-after', revisitAfter);\r\n }\r\n\r\n // Set rating\r\n if (rating) {\r\n setMetaTag('rating', rating);\r\n }\r\n\r\n // Set distribution\r\n if (distribution) {\r\n setMetaTag('distribution', distribution);\r\n }\r\n\r\n // Set copyright\r\n if (copyright) {\r\n setMetaTag('copyright', copyright);\r\n }\r\n\r\n // Set theme-color\r\n if (themeColor) {\r\n setMetaTag('theme-color', themeColor);\r\n }\r\n\r\n // Set referrer\r\n if (referrer) {\r\n setMetaTag('referrer', referrer);\r\n }\r\n\r\n // Set format-detection\r\n if (formatDetection) {\r\n setMetaTag('format-detection', formatDetection);\r\n }\r\n\r\n // Set mobile-web-app-capable\r\n if (mobileWebAppCapable) {\r\n setMetaTag('mobile-web-app-capable', mobileWebAppCapable);\r\n }\r\n\r\n // Set apple-mobile-web-app-capable\r\n if (appleMobileWebAppCapable) {\r\n setMetaTag('apple-mobile-web-app-capable', appleMobileWebAppCapable);\r\n }\r\n\r\n // Set geo tags\r\n if (geoRegion) {\r\n setMetaTag('geo.region', geoRegion);\r\n }\r\n if (geoPlacename) {\r\n setMetaTag('geo.placename', geoPlacename);\r\n }\r\n if (geoPosition) {\r\n setMetaTag('geo.position', geoPosition);\r\n }\r\n if (icbm) {\r\n setMetaTag('ICBM', icbm);\r\n }\r\n\r\n // Set canonical URL\r\n if (canonical) {\r\n setCanonical(canonical);\r\n }\r\n\r\n // Build Open Graph object\r\n const ogData: any = {\r\n ...openGraph,\r\n };\r\n\r\n if (ogTitle || title) {\r\n ogData.title = ogTitle || title;\r\n }\r\n if (ogDescription || description) {\r\n ogData.description = ogDescription || description;\r\n }\r\n if (ogType) {\r\n ogData.type = ogType;\r\n }\r\n if (ogUrl || canonical) {\r\n ogData.url = ogUrl || canonical;\r\n }\r\n if (ogImage) {\r\n ogData.image = ogImage;\r\n }\r\n if (ogSiteName) {\r\n ogData.siteName = ogSiteName;\r\n }\r\n if (ogLocale) {\r\n ogData.locale = ogLocale;\r\n }\r\n\r\n if (Object.keys(ogData).length > 0) {\r\n setOpenGraphTags(ogData);\r\n }\r\n\r\n // Build Twitter Card object\r\n const twitterData: any = {\r\n ...twitter,\r\n };\r\n\r\n if (twitterCard) {\r\n twitterData.card = twitterCard;\r\n }\r\n if (twitterSite) {\r\n twitterData.site = twitterSite;\r\n }\r\n if (twitterCreator) {\r\n twitterData.creator = twitterCreator;\r\n }\r\n if (twitterTitle || title) {\r\n twitterData.title = twitterTitle || title;\r\n }\r\n if (twitterDescription || description) {\r\n twitterData.description = twitterDescription || description;\r\n }\r\n if (twitterImage || ogImage) {\r\n twitterData.image = twitterImage || ogImage;\r\n }\r\n if (twitterImageAlt) {\r\n twitterData.imageAlt = twitterImageAlt;\r\n }\r\n\r\n if (Object.keys(twitterData).length > 0) {\r\n setTwitterCardTags(twitterData);\r\n }\r\n\r\n // Set custom meta tags\r\n if (customMeta) {\r\n setCustomMetaTags(customMeta);\r\n }\r\n\r\n // Inject JSON-LD\r\n if (jsonLd) {\r\n injectJsonLd(jsonLd, JSON_LD_ID);\r\n }\r\n\r\n // Inject Google Analytics\r\n if (googleAnalyticsId) {\r\n injectGoogleAnalytics(googleAnalyticsId);\r\n }\r\n\r\n // Inject Google Tag Manager\r\n if (googleTagManagerId) {\r\n injectGoogleTagManager(googleTagManagerId);\r\n }\r\n\r\n // Inject custom scripts\r\n if (customScripts && Array.isArray(customScripts)) {\r\n customScripts.forEach((scriptConfig) => {\r\n injectCustomScript(scriptConfig);\r\n });\r\n }\r\n }, []);\r\n\r\n const clearSeo = useCallback(() => {\r\n // Note: We don't clear title, description, keywords as they might be set by other means\r\n // Only clear what we manage\r\n removeCanonical();\r\n removeJsonLd(JSON_LD_ID);\r\n }, []);\r\n\r\n return {\r\n updateSeo,\r\n clearSeo,\r\n };\r\n}\r\n\r\n"],"names":["getOrCreateMetaTag","attribute","value","selector","element","setMetaTag","name","content","setMetaProperty","property","setTitle","title","setCanonical","url","link","removeCanonical","setOpenGraphTags","og","key","setTwitterCardTags","twitter","setCustomMetaTags","customMeta","meta","charsetElement","injectJsonLd","data","id","script","existing","removeJsonLd","formatKeywords","keywords","removeScript","injectGoogleAnalytics","GA_SCRIPT_ID","GA_CONFIG_ID","configScript","injectGoogleTagManager","GTM_SCRIPT_ID","GTM_NOSCRIPT_ID","existingNoscript","noscript","noscriptEl","injectCustomScript","scriptConfig","scriptId","JSON_LD_ID","Seo","description","author","robots","language","viewport","generator","revisitAfter","rating","distribution","copyright","themeColor","referrer","formatDetection","mobileWebAppCapable","appleMobileWebAppCapable","geoRegion","geoPlacename","geoPosition","icbm","canonical","ogImage","ogType","ogUrl","ogTitle","ogDescription","ogSiteName","ogLocale","twitterCard","twitterSite","twitterCreator","twitterTitle","twitterDescription","twitterImage","twitterImageAlt","jsonLd","openGraph","googleAnalyticsId","googleTagManagerId","customScripts","useEffect","keywordsStr","ogData","twitterData","cleanupJsonLd","cleanupGA","cleanupGTM","cleanupCustomScripts","cleanup","useSeo","updateSeo","useCallback","props","clearSeo"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -41,6 +41,25 @@ export interface CustomMeta {
41
41
  * JSON-LD structured data
42
42
  */
43
43
  export type JsonLd = Record<string, any> | Array<Record<string, any>>;
44
+ /**
45
+ * Custom script configuration
46
+ */
47
+ export interface CustomScript {
48
+ /** External script URL */
49
+ src?: string;
50
+ /** Inline script content */
51
+ content?: string;
52
+ /** Script element ID (for cleanup/updates) */
53
+ id?: string;
54
+ /** Async loading */
55
+ async?: boolean;
56
+ /** Defer loading */
57
+ defer?: boolean;
58
+ /** Script type (default: "text/javascript") */
59
+ type?: string;
60
+ /** Loading strategy */
61
+ strategy?: 'async' | 'defer' | 'sync';
62
+ }
44
63
  /**
45
64
  * SEO component props
46
65
  */
@@ -114,6 +133,12 @@ export interface SeoProps {
114
133
  openGraph?: OpenGraphMeta;
115
134
  /** Additional Twitter Card properties */
116
135
  twitter?: TwitterCardMeta;
136
+ /** Google Analytics ID (gtag.js) */
137
+ googleAnalyticsId?: string;
138
+ /** Google Tag Manager ID */
139
+ googleTagManagerId?: string;
140
+ /** Custom scripts to inject */
141
+ customScripts?: CustomScript[];
117
142
  }
118
143
  /**
119
144
  * Hook return type
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSeo.d.ts","sourceRoot":"","sources":["../src/useSeo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAY,YAAY,EAAE,MAAM,SAAS,CAAC;AAgBtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,IAAI,YAAY,CA2OrC"}
1
+ {"version":3,"file":"useSeo.d.ts","sourceRoot":"","sources":["../src/useSeo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAY,YAAY,EAAE,MAAM,SAAS,CAAC;AAmBtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,IAAI,YAAY,CA+PrC"}
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CustomMeta, JsonLd, OpenGraphMeta, TwitterCardMeta } from './types';
1
+ import { CustomMeta, CustomScript, JsonLd, OpenGraphMeta, TwitterCardMeta } from './types';
2
2
 
3
3
  /**
4
4
  * Set a meta tag by name
@@ -44,4 +44,20 @@ export declare function removeJsonLd(id: string): void;
44
44
  * Format keywords as string
45
45
  */
46
46
  export declare function formatKeywords(keywords: string | string[] | undefined): string;
47
+ /**
48
+ * Remove script by id
49
+ */
50
+ export declare function removeScript(id: string): void;
51
+ /**
52
+ * Inject Google Analytics script
53
+ */
54
+ export declare function injectGoogleAnalytics(id: string): () => void;
55
+ /**
56
+ * Inject Google Tag Manager script
57
+ */
58
+ export declare function injectGoogleTagManager(id: string): () => void;
59
+ /**
60
+ * Inject custom script
61
+ */
62
+ export declare function injectCustomScript(scriptConfig: CustomScript): () => void;
47
63
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAkBlF;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAK9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKhF;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG5C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAU9C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAKtC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,CA2BxD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAuBjE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI,CAkChE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAkBlE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAK7C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CAM9E"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAkBhG;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAK9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKhF;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG5C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAU9C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAKtC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,CA2BxD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAuBjE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI,CAkChE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAkBlE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAK7C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CAM9E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAK7C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,IAAI,CA+B5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,IAAI,CAuC7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,IAAI,CA6CzE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-client-seo",
3
- "version": "1.0.1",
3
+ "version": "1.1.2",
4
4
  "description": "Lightweight client-side SEO renderer for React and Vite apps",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",