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/README.md +165 -64
- package/dist/Seo.d.ts +1 -1
- package/dist/Seo.d.ts.map +1 -1
- package/dist/index.cjs +12 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +238 -114
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/useSeo.d.ts.map +1 -1
- package/dist/utils.d.ts +17 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
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
|
|
|
@@ -36,7 +37,7 @@ pnpm add react-client-seo
|
|
|
36
37
|
### Component API
|
|
37
38
|
|
|
38
39
|
```tsx
|
|
39
|
-
import { Seo } from
|
|
40
|
+
import { Seo } from "react-client-seo";
|
|
40
41
|
|
|
41
42
|
function App() {
|
|
42
43
|
return (
|
|
@@ -44,7 +45,9 @@ function App() {
|
|
|
44
45
|
<Seo
|
|
45
46
|
title="My Page Title"
|
|
46
47
|
description="This is a great page about React SEO"
|
|
47
|
-
keywords={[
|
|
48
|
+
keywords={["react", "seo", "meta tags"]}
|
|
49
|
+
author="John Doe"
|
|
50
|
+
robots="index, follow"
|
|
48
51
|
canonical="https://example.com/page"
|
|
49
52
|
/>
|
|
50
53
|
<div>Your content here</div>
|
|
@@ -56,17 +59,17 @@ function App() {
|
|
|
56
59
|
### Hook API
|
|
57
60
|
|
|
58
61
|
```tsx
|
|
59
|
-
import { useSeo } from
|
|
60
|
-
import { useEffect } from
|
|
62
|
+
import { useSeo } from "react-client-seo";
|
|
63
|
+
import { useEffect } from "react";
|
|
61
64
|
|
|
62
65
|
function MyComponent() {
|
|
63
66
|
const { updateSeo } = useSeo();
|
|
64
67
|
|
|
65
68
|
useEffect(() => {
|
|
66
69
|
updateSeo({
|
|
67
|
-
title:
|
|
68
|
-
description:
|
|
69
|
-
keywords:
|
|
70
|
+
title: "My Page Title",
|
|
71
|
+
description: "Page description",
|
|
72
|
+
keywords: "react, seo",
|
|
70
73
|
});
|
|
71
74
|
}, []);
|
|
72
75
|
|
|
@@ -83,6 +86,87 @@ function MyComponent() {
|
|
|
83
86
|
title="Home Page"
|
|
84
87
|
description="Welcome to our website"
|
|
85
88
|
keywords="home, welcome, website"
|
|
89
|
+
author="John Doe"
|
|
90
|
+
robots="index, follow"
|
|
91
|
+
language="en"
|
|
92
|
+
viewport="width=device-width, initial-scale=1"
|
|
93
|
+
/>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Geo Tags
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<Seo
|
|
100
|
+
title="Location Page"
|
|
101
|
+
description="Our location"
|
|
102
|
+
geoRegion="US-NY"
|
|
103
|
+
geoPlacename="New York"
|
|
104
|
+
geoPosition="40.7128;-74.0060"
|
|
105
|
+
icbm="40.7128, -74.0060"
|
|
106
|
+
/>
|
|
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
|
+
### Google Tag Manager
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
<Seo
|
|
123
|
+
title="My Page"
|
|
124
|
+
description="Page description"
|
|
125
|
+
googleTagManagerId="GTM-XXXXXXX"
|
|
126
|
+
/>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Custom Scripts
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
// External script
|
|
133
|
+
<Seo
|
|
134
|
+
title="My Page"
|
|
135
|
+
customScripts={[
|
|
136
|
+
{
|
|
137
|
+
src: "https://example.com/script.js",
|
|
138
|
+
id: "my-script",
|
|
139
|
+
async: true,
|
|
140
|
+
},
|
|
141
|
+
]}
|
|
142
|
+
/>
|
|
143
|
+
|
|
144
|
+
// Inline script
|
|
145
|
+
<Seo
|
|
146
|
+
title="My Page"
|
|
147
|
+
customScripts={[
|
|
148
|
+
{
|
|
149
|
+
content: "console.log('Hello from inline script');",
|
|
150
|
+
id: "inline-script",
|
|
151
|
+
},
|
|
152
|
+
]}
|
|
153
|
+
/>
|
|
154
|
+
|
|
155
|
+
// Multiple scripts with different strategies
|
|
156
|
+
<Seo
|
|
157
|
+
title="My Page"
|
|
158
|
+
customScripts={[
|
|
159
|
+
{
|
|
160
|
+
src: "https://example.com/async-script.js",
|
|
161
|
+
id: "async-script",
|
|
162
|
+
strategy: "async",
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
src: "https://example.com/defer-script.js",
|
|
166
|
+
id: "defer-script",
|
|
167
|
+
strategy: "defer",
|
|
168
|
+
},
|
|
169
|
+
]}
|
|
86
170
|
/>
|
|
87
171
|
```
|
|
88
172
|
|
|
@@ -123,14 +207,14 @@ function MyComponent() {
|
|
|
123
207
|
jsonLd={{
|
|
124
208
|
"@context": "https://schema.org",
|
|
125
209
|
"@type": "Product",
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
210
|
+
name: "Amazing Product",
|
|
211
|
+
description: "This is an amazing product",
|
|
212
|
+
image: "https://example.com/product.jpg",
|
|
213
|
+
offers: {
|
|
130
214
|
"@type": "Offer",
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
215
|
+
price: "99.99",
|
|
216
|
+
priceCurrency: "USD",
|
|
217
|
+
},
|
|
134
218
|
}}
|
|
135
219
|
/>
|
|
136
220
|
```
|
|
@@ -169,7 +253,7 @@ function MyComponent() {
|
|
|
169
253
|
### Complete Example
|
|
170
254
|
|
|
171
255
|
```tsx
|
|
172
|
-
import { Seo } from
|
|
256
|
+
import { Seo } from "react-client-seo";
|
|
173
257
|
|
|
174
258
|
function ProductPage({ product }) {
|
|
175
259
|
return (
|
|
@@ -189,19 +273,17 @@ function ProductPage({ product }) {
|
|
|
189
273
|
jsonLd={{
|
|
190
274
|
"@context": "https://schema.org",
|
|
191
275
|
"@type": "Product",
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
276
|
+
name: product.name,
|
|
277
|
+
description: product.description,
|
|
278
|
+
image: product.image,
|
|
279
|
+
offers: {
|
|
196
280
|
"@type": "Offer",
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
281
|
+
price: product.price,
|
|
282
|
+
priceCurrency: "USD",
|
|
283
|
+
availability: "https://schema.org/InStock",
|
|
284
|
+
},
|
|
201
285
|
}}
|
|
202
|
-
customMeta={[
|
|
203
|
-
{ name: "robots", content: "index, follow" },
|
|
204
|
-
]}
|
|
286
|
+
customMeta={[{ name: "robots", content: "index, follow" }]}
|
|
205
287
|
/>
|
|
206
288
|
<div>
|
|
207
289
|
<h1>{product.name}</h1>
|
|
@@ -216,30 +298,51 @@ function ProductPage({ product }) {
|
|
|
216
298
|
|
|
217
299
|
### `<Seo />` Component Props
|
|
218
300
|
|
|
219
|
-
| Prop
|
|
220
|
-
|
|
221
|
-
| `title`
|
|
222
|
-
| `description`
|
|
223
|
-
| `keywords`
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
226
|
-
| `
|
|
227
|
-
| `
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
230
|
-
| `
|
|
231
|
-
| `
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
234
|
-
| `
|
|
235
|
-
| `
|
|
236
|
-
| `
|
|
237
|
-
| `
|
|
238
|
-
| `
|
|
239
|
-
| `
|
|
240
|
-
| `
|
|
241
|
-
| `
|
|
242
|
-
| `
|
|
301
|
+
| Prop | Type | Description |
|
|
302
|
+
| -------------------------- | --------------------------------------------------------- | ----------------------------------------------------------- |
|
|
303
|
+
| `title` | `string` | Page title |
|
|
304
|
+
| `description` | `string` | Meta description |
|
|
305
|
+
| `keywords` | `string \| string[]` | Meta keywords (comma-separated string or array) |
|
|
306
|
+
| `author` | `string` | Meta author |
|
|
307
|
+
| `robots` | `string` | Meta robots (e.g., "index, follow", "noindex, nofollow") |
|
|
308
|
+
| `language` | `string` | Meta language/Content-Language |
|
|
309
|
+
| `viewport` | `string` | Meta viewport (e.g., "width=device-width, initial-scale=1") |
|
|
310
|
+
| `generator` | `string` | Meta generator |
|
|
311
|
+
| `revisitAfter` | `string` | Meta revisit-after (e.g., "7 days") |
|
|
312
|
+
| `rating` | `string` | Meta rating |
|
|
313
|
+
| `distribution` | `string` | Meta distribution |
|
|
314
|
+
| `copyright` | `string` | Meta copyright |
|
|
315
|
+
| `themeColor` | `string` | Meta theme-color |
|
|
316
|
+
| `referrer` | `string` | Meta referrer |
|
|
317
|
+
| `formatDetection` | `string` | Meta format-detection (mobile) |
|
|
318
|
+
| `mobileWebAppCapable` | `string` | Meta mobile-web-app-capable |
|
|
319
|
+
| `appleMobileWebAppCapable` | `string` | Meta apple-mobile-web-app-capable |
|
|
320
|
+
| `geoRegion` | `string` | Geo region (e.g., "US-NY") |
|
|
321
|
+
| `geoPlacename` | `string` | Geo placename |
|
|
322
|
+
| `geoPosition` | `string` | Geo position (e.g., "latitude;longitude") |
|
|
323
|
+
| `icbm` | `string` | ICBM coordinates (e.g., "latitude, longitude") |
|
|
324
|
+
| `canonical` | `string` | Canonical URL |
|
|
325
|
+
| `ogImage` | `string` | Open Graph image URL |
|
|
326
|
+
| `ogType` | `string` | Open Graph type (e.g., "article", "website") |
|
|
327
|
+
| `ogUrl` | `string` | Open Graph URL |
|
|
328
|
+
| `ogTitle` | `string` | Open Graph title (defaults to `title`) |
|
|
329
|
+
| `ogDescription` | `string` | Open Graph description (defaults to `description`) |
|
|
330
|
+
| `ogSiteName` | `string` | Open Graph site name |
|
|
331
|
+
| `ogLocale` | `string` | Open Graph locale |
|
|
332
|
+
| `twitterCard` | `'summary' \| 'summary_large_image' \| 'app' \| 'player'` | Twitter Card type |
|
|
333
|
+
| `twitterSite` | `string` | Twitter site handle |
|
|
334
|
+
| `twitterCreator` | `string` | Twitter creator handle |
|
|
335
|
+
| `twitterTitle` | `string` | Twitter title (defaults to `title`) |
|
|
336
|
+
| `twitterDescription` | `string` | Twitter description (defaults to `description`) |
|
|
337
|
+
| `twitterImage` | `string` | Twitter image URL |
|
|
338
|
+
| `twitterImageAlt` | `string` | Twitter image alt text |
|
|
339
|
+
| `jsonLd` | `object \| object[]` | JSON-LD structured data |
|
|
340
|
+
| `customMeta` | `CustomMeta[]` | Custom meta tags |
|
|
341
|
+
| `openGraph` | `OpenGraphMeta` | Additional Open Graph properties |
|
|
342
|
+
| `twitter` | `TwitterCardMeta` | Additional Twitter Card properties |
|
|
343
|
+
| `googleAnalyticsId` | `string` | Google Analytics ID (gtag.js) |
|
|
344
|
+
| `googleTagManagerId` | `string` | Google Tag Manager ID |
|
|
345
|
+
| `customScripts` | `CustomScript[]` | Custom scripts to inject (external or inline) |
|
|
243
346
|
|
|
244
347
|
### `useSeo()` Hook
|
|
245
348
|
|
|
@@ -253,7 +356,14 @@ Returns an object with:
|
|
|
253
356
|
Full TypeScript support is included. Import types as needed:
|
|
254
357
|
|
|
255
358
|
```tsx
|
|
256
|
-
import type {
|
|
359
|
+
import type {
|
|
360
|
+
SeoProps,
|
|
361
|
+
OpenGraphMeta,
|
|
362
|
+
TwitterCardMeta,
|
|
363
|
+
CustomMeta,
|
|
364
|
+
CustomScript,
|
|
365
|
+
JsonLd,
|
|
366
|
+
} from "react-client-seo";
|
|
257
367
|
```
|
|
258
368
|
|
|
259
369
|
## How It Works
|
|
@@ -264,19 +374,11 @@ import type { SeoProps, OpenGraphMeta, TwitterCardMeta, CustomMeta, JsonLd } fro
|
|
|
264
374
|
- Cleans up JSON-LD scripts on unmount (component API)
|
|
265
375
|
- Works entirely client-side - no SSR required
|
|
266
376
|
|
|
267
|
-
##
|
|
377
|
+
## Author
|
|
268
378
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
npm run build
|
|
273
|
-
```
|
|
274
|
-
3. Publish:
|
|
275
|
-
```bash
|
|
276
|
-
npm publish
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
The `prepare` script automatically runs before publishing, ensuring the package is built.
|
|
379
|
+
**Rainard Joseph**
|
|
380
|
+
I'm working as a Software Project Manager at [Odidor](https://odidor.app/), working on the ERP and IMS software products. I love coding.
|
|
381
|
+
Connect with on [LinkedIn](https://www.linkedin.com/in/rainard-joseph)
|
|
280
382
|
|
|
281
383
|
## License
|
|
282
384
|
|
|
@@ -285,4 +387,3 @@ MIT
|
|
|
285
387
|
## Contributing
|
|
286
388
|
|
|
287
389
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
288
|
-
|
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, 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;
|
|
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
|
|
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
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 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":"yGAKA,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,EAASC,EAAqB,CACvCA,IACL,SAAS,MAAQA,EACnB,CAKO,SAASC,EAAaC,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,GAAwB,CACtC,MAAMD,EAAO,SAAS,cAA+B,uBAAuB,EACxEA,GACFA,EAAK,OAAA,CAET,CAKO,SAASE,EAAiBC,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,EAAmBC,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,EAAkBC,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,EAAaC,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,EAAaH,EAAkB,CAC7C,MAAMC,EAAS,SAAS,eAAeD,CAAE,EACrCC,GAAUA,EAAO,aAAa,MAAM,IAAM,uBAC5CA,EAAO,OAAA,CAEX,CAKO,SAASG,EAAeC,EAAiD,CAC9E,OAAKA,EACD,MAAM,QAAQA,CAAQ,EACjBA,EAAS,KAAK,IAAI,EAEpBA,EAJe,EAKxB,CCvMA,MAAMC,EAAa,0BAoBZ,SAASC,EAAI,CAClB,MAAAvB,EACA,YAAAwB,EACA,SAAAH,EACA,UAAAI,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,WAAA7B,EACA,UAAA8B,EACA,QAAAhC,CACF,EAAa,CACXiC,OAAAA,EAAAA,UAAU,IAAM,CAEV1C,GACFD,EAASC,CAAK,EAIZwB,GACF9B,EAAW,cAAe8B,CAAW,EAIvC,MAAMmB,EAAcvB,EAAeC,CAAQ,EACvCsB,GACFjD,EAAW,WAAYiD,CAAW,EAIhClB,GACFxB,EAAawB,CAAS,EAIxB,MAAMmB,EAAc,CAClB,GAAGH,CAAA,GAGDZ,GAAW7B,KACb4C,EAAO,MAAQf,GAAW7B,IAExB8B,GAAiBN,KACnBoB,EAAO,YAAcd,GAAiBN,GAEpCG,IACFiB,EAAO,KAAOjB,IAEZC,GAASH,KACXmB,EAAO,IAAMhB,GAASH,GAEpBC,IACFkB,EAAO,MAAQlB,GAEbK,IACFa,EAAO,SAAWb,GAEhBC,IACFY,EAAO,OAASZ,GAGd,OAAO,KAAKY,CAAM,EAAE,OAAS,GAC/BvC,EAAiBuC,CAAM,EAIzB,MAAMC,EAAmB,CACvB,GAAGpC,CAAA,EAGDwB,IACFY,EAAY,KAAOZ,GAEjBC,IACFW,EAAY,KAAOX,GAEjBC,IACFU,EAAY,QAAUV,IAEpBC,GAAgBpC,KAClB6C,EAAY,MAAQT,GAAgBpC,IAElCqC,GAAsBb,KACxBqB,EAAY,YAAcR,GAAsBb,IAE9Cc,GAAgBZ,KAClBmB,EAAY,MAAQP,GAAgBZ,GAElCa,IACFM,EAAY,SAAWN,GAGrB,OAAO,KAAKM,CAAW,EAAE,OAAS,GACpCrC,EAAmBqC,CAAW,EAI5BlC,GACFD,EAAkBC,CAAU,EAI9B,IAAImC,EAAqC,KACzC,OAAIN,IACFM,EAAgBhC,EAAa0B,EAAQlB,CAAU,GAI1C,IAAM,CACPwB,GACFA,EAAA,CAEJ,CACF,EAAG,CACD9C,EACAwB,EACAH,EACAI,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACA7B,EACA8B,EACAhC,CAAA,CACD,EAEM,IACT,CCzKA,MAAMa,EAAa,0BAuBZ,SAASyB,GAAuB,CACrC,MAAMC,EAAYC,cAAaC,GAAoB,CACjD,KAAM,CACJ,MAAAlD,EACA,YAAAwB,EACA,SAAAH,EACA,UAAAI,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,WAAA7B,EACA,UAAA8B,EACA,QAAAhC,CAAA,EACEyC,EAGAlD,GACFD,EAASC,CAAK,EAIZwB,GACF9B,EAAW,cAAe8B,CAAW,EAIvC,MAAMmB,EAAcvB,EAAeC,CAAQ,EACvCsB,GACFjD,EAAW,WAAYiD,CAAW,EAIhClB,GACFxB,EAAawB,CAAS,EAIxB,MAAMmB,EAAc,CAClB,GAAGH,CAAA,GAGDZ,GAAW7B,KACb4C,EAAO,MAAQf,GAAW7B,IAExB8B,GAAiBN,KACnBoB,EAAO,YAAcd,GAAiBN,GAEpCG,IACFiB,EAAO,KAAOjB,IAEZC,GAASH,KACXmB,EAAO,IAAMhB,GAASH,GAEpBC,IACFkB,EAAO,MAAQlB,GAEbK,IACFa,EAAO,SAAWb,GAEhBC,IACFY,EAAO,OAASZ,GAGd,OAAO,KAAKY,CAAM,EAAE,OAAS,GAC/BvC,EAAiBuC,CAAM,EAIzB,MAAMC,EAAmB,CACvB,GAAGpC,CAAA,EAGDwB,IACFY,EAAY,KAAOZ,GAEjBC,IACFW,EAAY,KAAOX,GAEjBC,IACFU,EAAY,QAAUV,IAEpBC,GAAgBpC,KAClB6C,EAAY,MAAQT,GAAgBpC,IAElCqC,GAAsBb,KACxBqB,EAAY,YAAcR,GAAsBb,IAE9Cc,GAAgBZ,KAClBmB,EAAY,MAAQP,GAAgBZ,GAElCa,IACFM,EAAY,SAAWN,GAGrB,OAAO,KAAKM,CAAW,EAAE,OAAS,GACpCrC,EAAmBqC,CAAW,EAI5BlC,GACFD,EAAkBC,CAAU,EAI1B6B,GACF1B,EAAa0B,EAAQlB,CAAU,CAEnC,EAAG,CAAA,CAAE,EAEC6B,EAAWF,EAAAA,YAAY,IAAM,CAGjC7C,EAAA,EACAe,EAAaG,CAAU,CACzB,EAAG,CAAA,CAAE,EAEL,MAAO,CACL,UAAA0B,EACA,SAAAG,CAAA,CAEJ"}
|
|
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":"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"}
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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"}
|