react-client-seo 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,189 +1,313 @@
1
- import { useEffect as M, useCallback as _ } from "react";
2
- function W(e, t) {
1
+ import { useEffect as pe, useCallback as te } from "react";
2
+ function k(e, t) {
3
3
  const i = `meta[${e}="${t}"]`;
4
- let n = document.querySelector(i);
5
- return n || (n = document.createElement("meta"), n.setAttribute(e, t), document.head.appendChild(n)), n;
4
+ let r = document.querySelector(i);
5
+ return r || (r = document.createElement("meta"), r.setAttribute(e, t), document.head.appendChild(r)), r;
6
6
  }
7
- function c(e, t) {
7
+ function n(e, t) {
8
8
  if (!t) return;
9
- W("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
- W("property", e).setAttribute("content", String(t));
13
+ k("property", e).setAttribute("content", String(t));
14
14
  }
15
- function $(e) {
15
+ function ne(e) {
16
16
  e && (document.title = e);
17
17
  }
18
- function x(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 P() {
23
+ function ge() {
24
24
  const e = document.querySelector('link[rel="canonical"]');
25
25
  e && e.remove();
26
26
  }
27
- function B(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
30
  const i = e[t];
31
- i != null && i !== "" && a(t, i);
31
+ i != null && i !== "" && l(t, i);
32
32
  }
33
33
  }));
34
34
  }
35
- function H(e) {
36
- e && (e.card && c("twitter:card", e.card), e.site && c("twitter:site", e.site), e.creator && c("twitter:creator", e.creator), e.title && c("twitter:title", e.title), e.description && c("twitter:description", e.description), e.image && c("twitter:image", e.image), e.imageAlt && c("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
38
  const i = e[t];
39
- i != null && i !== "" && c(t, String(i));
39
+ i != null && i !== "" && n(t, String(i));
40
40
  }
41
41
  }));
42
42
  }
43
- function L(e) {
43
+ function oe(e) {
44
44
  !e || !Array.isArray(e) || e.forEach((t) => {
45
45
  if (!t.content) return;
46
46
  let i = null;
47
47
  if (t.name)
48
- i = W("name", t.name);
48
+ i = k("name", t.name);
49
49
  else if (t.property)
50
- i = W("property", t.property);
50
+ i = k("property", t.property);
51
51
  else if (t.httpEquiv) {
52
- const n = `meta[http-equiv="${t.httpEquiv}"]`;
53
- i = document.querySelector(n), i || (i = document.createElement("meta"), i.setAttribute("http-equiv", t.httpEquiv), document.head.appendChild(i));
52
+ const r = `meta[http-equiv="${t.httpEquiv}"]`;
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
- let n = document.querySelector("meta[charset]");
56
- n || (n = document.createElement("meta"), n.setAttribute("charset", t.charset), document.head.insertBefore(n, document.head.firstChild));
55
+ let r = document.querySelector("meta[charset]");
56
+ r || (r = document.createElement("meta"), r.setAttribute("charset", t.charset), document.head.insertBefore(r, document.head.firstChild));
57
57
  return;
58
58
  }
59
59
  i && i.setAttribute("content", t.content);
60
60
  });
61
61
  }
62
- function G(e, t) {
62
+ function fe(e, t) {
63
63
  const i = document.createElement("script");
64
64
  i.type = "application/ld+json";
65
65
  {
66
66
  i.id = t;
67
- const n = document.getElementById(t);
68
- n && n.remove();
67
+ const r = document.getElementById(t);
68
+ r && r.remove();
69
69
  }
70
70
  return i.textContent = JSON.stringify(e), document.head.appendChild(i), () => {
71
71
  i.remove();
72
72
  };
73
73
  }
74
- function z(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 K(e) {
78
+ function se(e) {
79
79
  return e ? Array.isArray(e) ? e.join(", ") : e : "";
80
80
  }
81
- const F = "react-client-seo-jsonld";
82
- function R({
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
135
  keywords: i,
86
- canonical: n,
87
- ogImage: r,
88
- ogType: C,
89
- ogUrl: u,
90
- ogTitle: m,
91
- ogDescription: d,
92
- ogSiteName: p,
93
- ogLocale: h,
94
- twitterCard: g,
95
- twitterSite: A,
96
- twitterCreator: b,
97
- twitterTitle: v,
98
- twitterDescription: E,
99
- twitterImage: S,
100
- twitterImageAlt: j,
101
- jsonLd: y,
102
- customMeta: O,
103
- openGraph: N,
104
- twitter: D
136
+ author: r,
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
105
176
  }) {
106
- return M(() => {
107
- e && $(e), t && c("description", t);
108
- const J = K(i);
109
- J && c("keywords", J), n && x(n);
110
- const f = {
111
- ...N
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 = {
182
+ ...V
112
183
  };
113
- (m || e) && (f.title = m || e), (d || t) && (f.description = d || t), C && (f.type = C), (u || n) && (f.url = u || n), r && (f.image = r), p && (f.siteName = p), h && (f.locale = h), Object.keys(f).length > 0 && B(f);
114
- const o = {
115
- ...D
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
116
187
  };
117
- g && (o.card = g), A && (o.site = A), b && (o.creator = b), (v || e) && (o.title = v || e), (E || t) && (o.description = E || t), (S || r) && (o.image = S || r), j && (o.imageAlt = j), Object.keys(o).length > 0 && H(o), O && L(O);
118
- let q = null;
119
- return y && (q = G(y, F)), () => {
120
- q && q();
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());
121
201
  };
122
202
  }, [
123
203
  e,
124
204
  t,
125
205
  i,
126
- n,
127
206
  r,
128
- C,
129
- u,
130
- m,
207
+ a,
131
208
  d,
132
- p,
133
- h,
134
- g,
209
+ u,
210
+ w,
211
+ E,
212
+ v,
135
213
  A,
136
214
  b,
137
- v,
138
- E,
139
- S,
140
215
  j,
141
- y,
142
- O,
216
+ S,
217
+ T,
143
218
  N,
144
- D
219
+ O,
220
+ _,
221
+ D,
222
+ I,
223
+ C,
224
+ m,
225
+ p,
226
+ q,
227
+ g,
228
+ h,
229
+ B,
230
+ G,
231
+ L,
232
+ $,
233
+ x,
234
+ J,
235
+ M,
236
+ H,
237
+ P,
238
+ R,
239
+ W,
240
+ F,
241
+ V,
242
+ X,
243
+ K,
244
+ Y,
245
+ z
145
246
  ]), null;
146
247
  }
147
- const T = "react-client-seo-jsonld";
148
- function V() {
149
- const e = _((i) => {
248
+ const ie = "react-client-seo-jsonld";
249
+ function ve() {
250
+ const e = te((i) => {
150
251
  const {
151
- title: n,
152
- description: r,
153
- keywords: C,
154
- canonical: u,
155
- ogImage: m,
156
- ogType: d,
157
- ogUrl: p,
158
- ogTitle: h,
159
- ogDescription: g,
160
- ogSiteName: A,
161
- ogLocale: b,
162
- twitterCard: v,
163
- twitterSite: E,
164
- twitterCreator: S,
165
- twitterTitle: j,
166
- twitterDescription: y,
167
- twitterImage: O,
168
- twitterImageAlt: N,
169
- jsonLd: D,
170
- customMeta: J,
171
- openGraph: f,
172
- twitter: o
252
+ title: r,
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
173
295
  } = i;
174
- n && $(n), r && c("description", r);
175
- const q = K(C);
176
- q && c("keywords", q), u && x(u);
177
- const l = {
178
- ...f
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
179
301
  };
180
- (h || n) && (l.title = h || n), (g || r) && (l.description = g || r), d && (l.type = d), (p || u) && (l.url = p || u), m && (l.image = m), A && (l.siteName = A), b && (l.locale = b), Object.keys(l).length > 0 && B(l);
181
- const s = {
182
- ...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
183
305
  };
184
- v && (s.card = v), E && (s.site = E), S && (s.creator = S), (j || n) && (s.title = j || n), (y || r) && (s.description = y || r), (O || m) && (s.image = O || m), N && (s.imageAlt = N), Object.keys(s).length > 0 && H(s), J && L(J), D && G(D, T);
185
- }, []), t = _(() => {
186
- P(), z(T);
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);
187
311
  }, []);
188
312
  return {
189
313
  updateSeo: e,
@@ -191,7 +315,7 @@ function V() {
191
315
  };
192
316
  }
193
317
  export {
194
- R as Seo,
195
- V as useSeo
318
+ we as Seo,
319
+ ve as useSeo
196
320
  };
197
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 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 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 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 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 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","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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"}