@masters-ws/react-seo 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1361 -83
- package/dist/chunk-6RBCF5I5.mjs +567 -0
- package/dist/chunk-FFE2ZOOC.mjs +945 -0
- package/dist/chunk-L6YRMB7H.mjs +988 -0
- package/dist/core/index.d.mts +2 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.js +684 -40
- package/dist/core/index.mjs +29 -3
- package/dist/index-CkB-Wt4c.d.mts +1272 -0
- package/dist/index-CkB-Wt4c.d.ts +1272 -0
- package/dist/index-DEE7ZyDx.d.mts +1193 -0
- package/dist/index-DEE7ZyDx.d.ts +1193 -0
- package/dist/index-Wu9j5oCk.d.mts +721 -0
- package/dist/index-Wu9j5oCk.d.ts +721 -0
- package/dist/index.d.mts +13 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.js +794 -129
- package/dist/index.mjs +57 -10
- package/package.json +1 -1
|
@@ -0,0 +1,721 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface SiteConfig {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
url: string;
|
|
7
|
+
logo?: string;
|
|
8
|
+
publisher?: string;
|
|
9
|
+
twitterHandle?: string;
|
|
10
|
+
facebookAppId?: string;
|
|
11
|
+
language?: string;
|
|
12
|
+
socialLinks?: string[];
|
|
13
|
+
googleAnalyticsId?: string;
|
|
14
|
+
gtmId?: string;
|
|
15
|
+
facebookPixelId?: string;
|
|
16
|
+
yandexMetricaId?: string;
|
|
17
|
+
themeColor?: string;
|
|
18
|
+
manifest?: string;
|
|
19
|
+
}
|
|
20
|
+
interface SEOData {
|
|
21
|
+
title?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
image?: string;
|
|
24
|
+
canonical?: string;
|
|
25
|
+
type?: 'website' | 'article' | 'product' | 'profile' | 'video' | 'faq';
|
|
26
|
+
robots?: string;
|
|
27
|
+
noindex?: boolean;
|
|
28
|
+
keywords?: string[];
|
|
29
|
+
prev?: string;
|
|
30
|
+
next?: string;
|
|
31
|
+
alternates?: Array<{
|
|
32
|
+
hreflang: string;
|
|
33
|
+
href: string;
|
|
34
|
+
}>;
|
|
35
|
+
ogTitle?: string;
|
|
36
|
+
ogDescription?: string;
|
|
37
|
+
ogImage?: string;
|
|
38
|
+
ogImageWidth?: number;
|
|
39
|
+
ogImageHeight?: number;
|
|
40
|
+
ogImageAlt?: string;
|
|
41
|
+
ogType?: string;
|
|
42
|
+
ogLocale?: string;
|
|
43
|
+
twitterCard?: 'summary' | 'summary_large_image' | 'app' | 'player';
|
|
44
|
+
twitterTitle?: string;
|
|
45
|
+
twitterDescription?: string;
|
|
46
|
+
twitterImage?: string;
|
|
47
|
+
twitterImageAlt?: string;
|
|
48
|
+
publishedTime?: string;
|
|
49
|
+
modifiedTime?: string;
|
|
50
|
+
author?: {
|
|
51
|
+
name: string;
|
|
52
|
+
url?: string;
|
|
53
|
+
image?: string;
|
|
54
|
+
};
|
|
55
|
+
tags?: string[];
|
|
56
|
+
section?: string;
|
|
57
|
+
readingTime?: number;
|
|
58
|
+
product?: {
|
|
59
|
+
sku?: string;
|
|
60
|
+
brand?: string;
|
|
61
|
+
price?: number;
|
|
62
|
+
currency?: string;
|
|
63
|
+
availability?: string;
|
|
64
|
+
rating?: number;
|
|
65
|
+
reviewCount?: number;
|
|
66
|
+
};
|
|
67
|
+
dnsPrefetch?: string[];
|
|
68
|
+
preconnect?: string[];
|
|
69
|
+
prefetch?: string[];
|
|
70
|
+
preload?: Array<{
|
|
71
|
+
href: string;
|
|
72
|
+
as: string;
|
|
73
|
+
type?: string;
|
|
74
|
+
}>;
|
|
75
|
+
whatsappImage?: string;
|
|
76
|
+
whatsappDescription?: string;
|
|
77
|
+
schema?: any;
|
|
78
|
+
}
|
|
79
|
+
interface BreadcrumbItem {
|
|
80
|
+
name: string;
|
|
81
|
+
item: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Generate Organization Schema
|
|
86
|
+
*/
|
|
87
|
+
declare function generateOrganizationSchema(config: SiteConfig): {
|
|
88
|
+
"@context": string;
|
|
89
|
+
"@type": string;
|
|
90
|
+
name: string;
|
|
91
|
+
url: string;
|
|
92
|
+
logo: string | undefined;
|
|
93
|
+
sameAs: string[];
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Generate WebSite Schema with SearchAction
|
|
97
|
+
*/
|
|
98
|
+
declare function generateWebSiteSchema(config: SiteConfig): {
|
|
99
|
+
"@context": string;
|
|
100
|
+
"@type": string;
|
|
101
|
+
name: string;
|
|
102
|
+
url: string;
|
|
103
|
+
potentialAction: {
|
|
104
|
+
"@type": string;
|
|
105
|
+
target: string;
|
|
106
|
+
"query-input": string;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Generate NewsArticle Schema
|
|
111
|
+
*/
|
|
112
|
+
declare function generateArticleSchema(data: {
|
|
113
|
+
title: string;
|
|
114
|
+
description: string;
|
|
115
|
+
image?: string;
|
|
116
|
+
publishedTime?: string;
|
|
117
|
+
modifiedTime?: string;
|
|
118
|
+
author?: {
|
|
119
|
+
name: string;
|
|
120
|
+
url?: string;
|
|
121
|
+
};
|
|
122
|
+
url?: string;
|
|
123
|
+
}, config: SiteConfig): {
|
|
124
|
+
"@context": string;
|
|
125
|
+
"@type": string;
|
|
126
|
+
headline: string;
|
|
127
|
+
description: string;
|
|
128
|
+
image: string | undefined;
|
|
129
|
+
datePublished: string | undefined;
|
|
130
|
+
dateModified: string | undefined;
|
|
131
|
+
mainEntityOfPage: string | undefined;
|
|
132
|
+
author: {
|
|
133
|
+
"@context": string;
|
|
134
|
+
"@type": string;
|
|
135
|
+
name: string;
|
|
136
|
+
url: string;
|
|
137
|
+
logo: string | undefined;
|
|
138
|
+
sameAs: string[];
|
|
139
|
+
} | {
|
|
140
|
+
"@type": string;
|
|
141
|
+
name: string;
|
|
142
|
+
url: string | undefined;
|
|
143
|
+
};
|
|
144
|
+
publisher: {
|
|
145
|
+
"@context": string;
|
|
146
|
+
"@type": string;
|
|
147
|
+
name: string;
|
|
148
|
+
url: string;
|
|
149
|
+
logo: string | undefined;
|
|
150
|
+
sameAs: string[];
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Generate Product Schema
|
|
155
|
+
*/
|
|
156
|
+
declare function generateProductSchema(data: {
|
|
157
|
+
name: string;
|
|
158
|
+
description: string;
|
|
159
|
+
image?: string;
|
|
160
|
+
sku?: string;
|
|
161
|
+
brand?: string;
|
|
162
|
+
price?: number;
|
|
163
|
+
currency?: string;
|
|
164
|
+
availability?: string;
|
|
165
|
+
rating?: number;
|
|
166
|
+
reviewCount?: number;
|
|
167
|
+
url?: string;
|
|
168
|
+
}): {
|
|
169
|
+
"@context": string;
|
|
170
|
+
"@type": string;
|
|
171
|
+
name: string;
|
|
172
|
+
description: string;
|
|
173
|
+
image: string | undefined;
|
|
174
|
+
sku: string | undefined;
|
|
175
|
+
brand: {
|
|
176
|
+
"@type": string;
|
|
177
|
+
name: string;
|
|
178
|
+
} | undefined;
|
|
179
|
+
offers: {
|
|
180
|
+
"@type": string;
|
|
181
|
+
url: string | undefined;
|
|
182
|
+
priceCurrency: string;
|
|
183
|
+
price: number | undefined;
|
|
184
|
+
availability: string;
|
|
185
|
+
};
|
|
186
|
+
aggregateRating: {
|
|
187
|
+
"@type": string;
|
|
188
|
+
ratingValue: number;
|
|
189
|
+
reviewCount: number;
|
|
190
|
+
} | undefined;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Generate FAQ Schema
|
|
194
|
+
*/
|
|
195
|
+
declare function generateFAQSchema(questions: Array<{
|
|
196
|
+
q: string;
|
|
197
|
+
a: string;
|
|
198
|
+
}>): {
|
|
199
|
+
"@context": string;
|
|
200
|
+
"@type": string;
|
|
201
|
+
mainEntity: {
|
|
202
|
+
"@type": string;
|
|
203
|
+
name: string;
|
|
204
|
+
acceptedAnswer: {
|
|
205
|
+
"@type": string;
|
|
206
|
+
text: string;
|
|
207
|
+
};
|
|
208
|
+
}[];
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* Generate Breadcrumb Schema
|
|
212
|
+
*/
|
|
213
|
+
declare function generateBreadcrumbSchema(items: Array<{
|
|
214
|
+
name: string;
|
|
215
|
+
item: string;
|
|
216
|
+
}>): {
|
|
217
|
+
"@context": string;
|
|
218
|
+
"@type": string;
|
|
219
|
+
itemListElement: {
|
|
220
|
+
"@type": string;
|
|
221
|
+
position: number;
|
|
222
|
+
name: string;
|
|
223
|
+
item: string;
|
|
224
|
+
}[];
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* Generate Video Schema
|
|
228
|
+
*/
|
|
229
|
+
declare function generateVideoSchema(data: {
|
|
230
|
+
name: string;
|
|
231
|
+
description: string;
|
|
232
|
+
thumbnailUrl: string;
|
|
233
|
+
uploadDate: string;
|
|
234
|
+
duration?: string;
|
|
235
|
+
contentUrl?: string;
|
|
236
|
+
embedUrl?: string;
|
|
237
|
+
}): {
|
|
238
|
+
"@context": string;
|
|
239
|
+
"@type": string;
|
|
240
|
+
name: string;
|
|
241
|
+
description: string;
|
|
242
|
+
thumbnailUrl: string;
|
|
243
|
+
uploadDate: string;
|
|
244
|
+
duration: string | undefined;
|
|
245
|
+
contentUrl: string | undefined;
|
|
246
|
+
embedUrl: string | undefined;
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* Generate Event Schema
|
|
250
|
+
*/
|
|
251
|
+
declare function generateEventSchema(data: {
|
|
252
|
+
name: string;
|
|
253
|
+
description: string;
|
|
254
|
+
startDate: string;
|
|
255
|
+
endDate?: string;
|
|
256
|
+
location?: {
|
|
257
|
+
name: string;
|
|
258
|
+
address: string;
|
|
259
|
+
} | {
|
|
260
|
+
url: string;
|
|
261
|
+
};
|
|
262
|
+
image?: string;
|
|
263
|
+
offers?: {
|
|
264
|
+
price: number;
|
|
265
|
+
currency: string;
|
|
266
|
+
url: string;
|
|
267
|
+
};
|
|
268
|
+
}): {
|
|
269
|
+
"@context": string;
|
|
270
|
+
"@type": string;
|
|
271
|
+
name: string;
|
|
272
|
+
description: string;
|
|
273
|
+
startDate: string;
|
|
274
|
+
endDate: string | undefined;
|
|
275
|
+
eventAttendanceMode: string;
|
|
276
|
+
location: {
|
|
277
|
+
"@type": string;
|
|
278
|
+
url: string;
|
|
279
|
+
name?: undefined;
|
|
280
|
+
address?: undefined;
|
|
281
|
+
} | {
|
|
282
|
+
"@type": string;
|
|
283
|
+
name: string;
|
|
284
|
+
address: string;
|
|
285
|
+
url?: undefined;
|
|
286
|
+
} | undefined;
|
|
287
|
+
image: string | undefined;
|
|
288
|
+
offers: {
|
|
289
|
+
"@type": string;
|
|
290
|
+
price: number;
|
|
291
|
+
priceCurrency: string;
|
|
292
|
+
url: string;
|
|
293
|
+
} | undefined;
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* Generate LocalBusiness Schema
|
|
297
|
+
*/
|
|
298
|
+
declare function generateLocalBusinessSchema(data: {
|
|
299
|
+
name: string;
|
|
300
|
+
description: string;
|
|
301
|
+
image?: string;
|
|
302
|
+
telephone?: string;
|
|
303
|
+
address: {
|
|
304
|
+
street: string;
|
|
305
|
+
city: string;
|
|
306
|
+
region?: string;
|
|
307
|
+
postalCode?: string;
|
|
308
|
+
country: string;
|
|
309
|
+
};
|
|
310
|
+
geo?: {
|
|
311
|
+
lat: number;
|
|
312
|
+
lng: number;
|
|
313
|
+
};
|
|
314
|
+
openingHours?: string[];
|
|
315
|
+
priceRange?: string;
|
|
316
|
+
}): {
|
|
317
|
+
"@context": string;
|
|
318
|
+
"@type": string;
|
|
319
|
+
name: string;
|
|
320
|
+
description: string;
|
|
321
|
+
image: string | undefined;
|
|
322
|
+
telephone: string | undefined;
|
|
323
|
+
address: {
|
|
324
|
+
"@type": string;
|
|
325
|
+
streetAddress: string;
|
|
326
|
+
addressLocality: string;
|
|
327
|
+
addressRegion: string | undefined;
|
|
328
|
+
postalCode: string | undefined;
|
|
329
|
+
addressCountry: string;
|
|
330
|
+
};
|
|
331
|
+
geo: {
|
|
332
|
+
"@type": string;
|
|
333
|
+
latitude: number;
|
|
334
|
+
longitude: number;
|
|
335
|
+
} | undefined;
|
|
336
|
+
openingHours: string[] | undefined;
|
|
337
|
+
priceRange: string | undefined;
|
|
338
|
+
};
|
|
339
|
+
/**
|
|
340
|
+
* Generate SoftwareApplication Schema
|
|
341
|
+
*/
|
|
342
|
+
declare function generateSoftwareSchema(data: {
|
|
343
|
+
name: string;
|
|
344
|
+
description: string;
|
|
345
|
+
operatingSystem?: string;
|
|
346
|
+
applicationCategory?: string;
|
|
347
|
+
offers?: {
|
|
348
|
+
price: number;
|
|
349
|
+
currency: string;
|
|
350
|
+
};
|
|
351
|
+
rating?: number;
|
|
352
|
+
reviewCount?: number;
|
|
353
|
+
downloadUrl?: string;
|
|
354
|
+
screenshot?: string;
|
|
355
|
+
}): {
|
|
356
|
+
"@context": string;
|
|
357
|
+
"@type": string;
|
|
358
|
+
name: string;
|
|
359
|
+
description: string;
|
|
360
|
+
operatingSystem: string | undefined;
|
|
361
|
+
applicationCategory: string | undefined;
|
|
362
|
+
offers: {
|
|
363
|
+
"@type": string;
|
|
364
|
+
price: number;
|
|
365
|
+
priceCurrency: string;
|
|
366
|
+
} | undefined;
|
|
367
|
+
aggregateRating: {
|
|
368
|
+
"@type": string;
|
|
369
|
+
ratingValue: number;
|
|
370
|
+
reviewCount: number;
|
|
371
|
+
} | undefined;
|
|
372
|
+
downloadUrl: string | undefined;
|
|
373
|
+
screenshot: string | undefined;
|
|
374
|
+
};
|
|
375
|
+
/**
|
|
376
|
+
* Generate Book Schema
|
|
377
|
+
*/
|
|
378
|
+
declare function generateBookSchema(data: {
|
|
379
|
+
name: string;
|
|
380
|
+
author: string | {
|
|
381
|
+
name: string;
|
|
382
|
+
url?: string;
|
|
383
|
+
};
|
|
384
|
+
description: string;
|
|
385
|
+
isbn?: string;
|
|
386
|
+
numberOfPages?: number;
|
|
387
|
+
publisher?: string;
|
|
388
|
+
datePublished?: string;
|
|
389
|
+
image?: string;
|
|
390
|
+
inLanguage?: string;
|
|
391
|
+
genre?: string;
|
|
392
|
+
}): {
|
|
393
|
+
"@context": string;
|
|
394
|
+
"@type": string;
|
|
395
|
+
name: string;
|
|
396
|
+
author: {
|
|
397
|
+
"@type": string;
|
|
398
|
+
name: string;
|
|
399
|
+
url?: undefined;
|
|
400
|
+
} | {
|
|
401
|
+
"@type": string;
|
|
402
|
+
name: string;
|
|
403
|
+
url: string | undefined;
|
|
404
|
+
};
|
|
405
|
+
description: string;
|
|
406
|
+
isbn: string | undefined;
|
|
407
|
+
numberOfPages: number | undefined;
|
|
408
|
+
publisher: {
|
|
409
|
+
"@type": string;
|
|
410
|
+
name: string;
|
|
411
|
+
} | undefined;
|
|
412
|
+
datePublished: string | undefined;
|
|
413
|
+
image: string | undefined;
|
|
414
|
+
inLanguage: string | undefined;
|
|
415
|
+
genre: string | undefined;
|
|
416
|
+
};
|
|
417
|
+
/**
|
|
418
|
+
* Generate Movie Schema
|
|
419
|
+
*/
|
|
420
|
+
declare function generateMovieSchema(data: {
|
|
421
|
+
name: string;
|
|
422
|
+
description: string;
|
|
423
|
+
image?: string;
|
|
424
|
+
director?: string;
|
|
425
|
+
actor?: string[];
|
|
426
|
+
dateCreated?: string;
|
|
427
|
+
duration?: string;
|
|
428
|
+
genre?: string[];
|
|
429
|
+
rating?: number;
|
|
430
|
+
reviewCount?: number;
|
|
431
|
+
}): {
|
|
432
|
+
"@context": string;
|
|
433
|
+
"@type": string;
|
|
434
|
+
name: string;
|
|
435
|
+
description: string;
|
|
436
|
+
image: string | undefined;
|
|
437
|
+
director: {
|
|
438
|
+
"@type": string;
|
|
439
|
+
name: string;
|
|
440
|
+
} | undefined;
|
|
441
|
+
actor: {
|
|
442
|
+
"@type": string;
|
|
443
|
+
name: string;
|
|
444
|
+
}[] | undefined;
|
|
445
|
+
dateCreated: string | undefined;
|
|
446
|
+
duration: string | undefined;
|
|
447
|
+
genre: string[] | undefined;
|
|
448
|
+
aggregateRating: {
|
|
449
|
+
"@type": string;
|
|
450
|
+
ratingValue: number;
|
|
451
|
+
reviewCount: number;
|
|
452
|
+
} | undefined;
|
|
453
|
+
};
|
|
454
|
+
/**
|
|
455
|
+
* Generate Podcast Schema (PodcastSeries)
|
|
456
|
+
*/
|
|
457
|
+
declare function generatePodcastSchema(data: {
|
|
458
|
+
name: string;
|
|
459
|
+
description: string;
|
|
460
|
+
image?: string;
|
|
461
|
+
author?: string;
|
|
462
|
+
webFeed?: string;
|
|
463
|
+
url?: string;
|
|
464
|
+
genre?: string;
|
|
465
|
+
}): {
|
|
466
|
+
"@context": string;
|
|
467
|
+
"@type": string;
|
|
468
|
+
name: string;
|
|
469
|
+
description: string;
|
|
470
|
+
image: string | undefined;
|
|
471
|
+
author: {
|
|
472
|
+
"@type": string;
|
|
473
|
+
name: string;
|
|
474
|
+
} | undefined;
|
|
475
|
+
webFeed: string | undefined;
|
|
476
|
+
url: string | undefined;
|
|
477
|
+
genre: string | undefined;
|
|
478
|
+
};
|
|
479
|
+
/**
|
|
480
|
+
* Generate PodcastEpisode Schema
|
|
481
|
+
*/
|
|
482
|
+
declare function generatePodcastEpisodeSchema(data: {
|
|
483
|
+
name: string;
|
|
484
|
+
description: string;
|
|
485
|
+
datePublished: string;
|
|
486
|
+
duration?: string;
|
|
487
|
+
url?: string;
|
|
488
|
+
audio?: string;
|
|
489
|
+
partOfSeries?: {
|
|
490
|
+
name: string;
|
|
491
|
+
url: string;
|
|
492
|
+
};
|
|
493
|
+
}): {
|
|
494
|
+
"@context": string;
|
|
495
|
+
"@type": string;
|
|
496
|
+
name: string;
|
|
497
|
+
description: string;
|
|
498
|
+
datePublished: string;
|
|
499
|
+
timeRequired: string | undefined;
|
|
500
|
+
url: string | undefined;
|
|
501
|
+
associatedMedia: {
|
|
502
|
+
"@type": string;
|
|
503
|
+
contentUrl: string;
|
|
504
|
+
} | undefined;
|
|
505
|
+
partOfSeries: {
|
|
506
|
+
"@type": string;
|
|
507
|
+
name: string;
|
|
508
|
+
url: string;
|
|
509
|
+
} | undefined;
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Converts SEOData and SiteConfig to a Next.js compatible Metadata object.
|
|
514
|
+
* This is designed to be used in Server Components (App Router).
|
|
515
|
+
*
|
|
516
|
+
* @example
|
|
517
|
+
* // In page.tsx (Server Component - no 'use client')
|
|
518
|
+
* import { toNextMetadata } from '@masters-ws/react-seo/core';
|
|
519
|
+
*
|
|
520
|
+
* export async function generateMetadata({ params }) {
|
|
521
|
+
* const post = await getPost(params.id);
|
|
522
|
+
* return toNextMetadata({ title: post.title, ... }, siteConfig);
|
|
523
|
+
* }
|
|
524
|
+
*/
|
|
525
|
+
declare function toNextMetadata(props: SEOData, config: SiteConfig): any;
|
|
526
|
+
/**
|
|
527
|
+
* Generates pagination links for category/tag pages.
|
|
528
|
+
* Returns { prev, next, canonical } URLs.
|
|
529
|
+
*/
|
|
530
|
+
declare function generatePaginationLinks(baseUrl: string, currentPage: number, totalPages: number): {
|
|
531
|
+
next: string | undefined;
|
|
532
|
+
prev: string | undefined;
|
|
533
|
+
canonical: string;
|
|
534
|
+
};
|
|
535
|
+
/**
|
|
536
|
+
* Generates title with page number suffix for paginated pages.
|
|
537
|
+
*/
|
|
538
|
+
declare function generatePaginatedTitle(title: string, page: number, suffix?: string): string;
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Server-safe JSON-LD component for Next.js App Router.
|
|
542
|
+
* Renders schema markup as <script type="application/ld+json"> in server-rendered HTML.
|
|
543
|
+
*
|
|
544
|
+
* Unlike Helmet-based components, this works in Server Components,
|
|
545
|
+
* so Google sees the schemas on first crawl without JavaScript execution.
|
|
546
|
+
*
|
|
547
|
+
* @example
|
|
548
|
+
* // In a Server Component (page.tsx without 'use client')
|
|
549
|
+
* import { JsonLd, generateProductSchema } from '@masters-ws/react-seo/core';
|
|
550
|
+
*
|
|
551
|
+
* export default function ProductPage() {
|
|
552
|
+
* const schema = generateProductSchema({ name: 'Product', ... });
|
|
553
|
+
* return (
|
|
554
|
+
* <>
|
|
555
|
+
* <JsonLd schema={schema} />
|
|
556
|
+
* <main>...</main>
|
|
557
|
+
* </>
|
|
558
|
+
* );
|
|
559
|
+
* }
|
|
560
|
+
*
|
|
561
|
+
* // Multiple schemas
|
|
562
|
+
* <JsonLd schema={[productSchema, breadcrumbSchema, orgSchema]} />
|
|
563
|
+
*/
|
|
564
|
+
interface JsonLdProps {
|
|
565
|
+
/** A single schema object or an array of schema objects */
|
|
566
|
+
schema: Record<string, any> | Record<string, any>[];
|
|
567
|
+
}
|
|
568
|
+
declare function JsonLd({ schema }: JsonLdProps): react_jsx_runtime.JSX.Element;
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Product metadata input for convenience helper
|
|
572
|
+
*/
|
|
573
|
+
interface ProductMetadataInput {
|
|
574
|
+
name: string;
|
|
575
|
+
description: string;
|
|
576
|
+
image?: string;
|
|
577
|
+
images?: string[];
|
|
578
|
+
sku?: string;
|
|
579
|
+
brand?: string;
|
|
580
|
+
price?: number;
|
|
581
|
+
currency?: string;
|
|
582
|
+
availability?: string;
|
|
583
|
+
rating?: number;
|
|
584
|
+
reviewCount?: number;
|
|
585
|
+
url: string;
|
|
586
|
+
metaTitle?: string;
|
|
587
|
+
metaDescription?: string;
|
|
588
|
+
canonical?: string;
|
|
589
|
+
noindex?: boolean;
|
|
590
|
+
breadcrumbs?: Array<{
|
|
591
|
+
name: string;
|
|
592
|
+
item: string;
|
|
593
|
+
}>;
|
|
594
|
+
category?: string;
|
|
595
|
+
ogImage?: string;
|
|
596
|
+
ogImageWidth?: number;
|
|
597
|
+
ogImageHeight?: number;
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Result from generateProductMetadata
|
|
601
|
+
*/
|
|
602
|
+
interface ProductMetadataResult {
|
|
603
|
+
/** Next.js Metadata object - use as return from generateMetadata() */
|
|
604
|
+
metadata: any;
|
|
605
|
+
/** All JSON-LD schemas for the product page */
|
|
606
|
+
schemas: Record<string, any>[];
|
|
607
|
+
/** Individual schemas for granular control */
|
|
608
|
+
productSchema: Record<string, any>;
|
|
609
|
+
breadcrumbSchema: Record<string, any>;
|
|
610
|
+
organizationSchema: Record<string, any>;
|
|
611
|
+
websiteSchema: Record<string, any>;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* All-in-one helper for product pages in Next.js App Router.
|
|
615
|
+
* Generates both the Metadata object AND all JSON-LD schemas in one call.
|
|
616
|
+
*
|
|
617
|
+
* @example
|
|
618
|
+
* ```tsx
|
|
619
|
+
* // app/products/[slug]/page.tsx (Server Component)
|
|
620
|
+
* import { generateProductMetadata, JsonLd } from '@masters-ws/react-seo/core';
|
|
621
|
+
*
|
|
622
|
+
* const siteConfig = { name: 'My Store', url: 'https://store.com', ... };
|
|
623
|
+
*
|
|
624
|
+
* export async function generateMetadata({ params }) {
|
|
625
|
+
* const product = await fetchProduct(params.slug);
|
|
626
|
+
* const { metadata } = generateProductMetadata(product, siteConfig);
|
|
627
|
+
* return metadata;
|
|
628
|
+
* }
|
|
629
|
+
*
|
|
630
|
+
* export default async function ProductPage({ params }) {
|
|
631
|
+
* const product = await fetchProduct(params.slug);
|
|
632
|
+
* const { schemas } = generateProductMetadata(product, siteConfig);
|
|
633
|
+
*
|
|
634
|
+
* return (
|
|
635
|
+
* <>
|
|
636
|
+
* <JsonLd schema={schemas} />
|
|
637
|
+
* <ProductDetailClient product={product} />
|
|
638
|
+
* </>
|
|
639
|
+
* );
|
|
640
|
+
* }
|
|
641
|
+
* ```
|
|
642
|
+
*/
|
|
643
|
+
declare function generateProductMetadata(product: ProductMetadataInput, config: SiteConfig): ProductMetadataResult;
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Article metadata input for convenience helper
|
|
647
|
+
*/
|
|
648
|
+
interface ArticleMetadataInput {
|
|
649
|
+
title: string;
|
|
650
|
+
description: string;
|
|
651
|
+
image?: string;
|
|
652
|
+
publishedTime: string;
|
|
653
|
+
modifiedTime?: string;
|
|
654
|
+
author?: {
|
|
655
|
+
name: string;
|
|
656
|
+
url?: string;
|
|
657
|
+
image?: string;
|
|
658
|
+
};
|
|
659
|
+
url: string;
|
|
660
|
+
category?: string;
|
|
661
|
+
tags?: string[];
|
|
662
|
+
readingTime?: number;
|
|
663
|
+
metaTitle?: string;
|
|
664
|
+
metaDescription?: string;
|
|
665
|
+
canonical?: string;
|
|
666
|
+
noindex?: boolean;
|
|
667
|
+
breadcrumbs?: Array<{
|
|
668
|
+
name: string;
|
|
669
|
+
item: string;
|
|
670
|
+
}>;
|
|
671
|
+
ogImage?: string;
|
|
672
|
+
ogImageWidth?: number;
|
|
673
|
+
ogImageHeight?: number;
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Result from generateArticleMetadata
|
|
677
|
+
*/
|
|
678
|
+
interface ArticleMetadataResult {
|
|
679
|
+
/** Next.js Metadata object - use as return from generateMetadata() */
|
|
680
|
+
metadata: any;
|
|
681
|
+
/** All JSON-LD schemas for the article page */
|
|
682
|
+
schemas: Record<string, any>[];
|
|
683
|
+
/** Individual schemas for granular control */
|
|
684
|
+
articleSchema: Record<string, any>;
|
|
685
|
+
breadcrumbSchema: Record<string, any>;
|
|
686
|
+
organizationSchema: Record<string, any>;
|
|
687
|
+
websiteSchema: Record<string, any>;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* All-in-one helper for article pages in Next.js App Router.
|
|
691
|
+
* Generates both the Metadata object AND all JSON-LD schemas in one call.
|
|
692
|
+
*
|
|
693
|
+
* @example
|
|
694
|
+
* ```tsx
|
|
695
|
+
* // app/news/[slug]/page.tsx (Server Component)
|
|
696
|
+
* import { generateArticleMetadata, JsonLd } from '@masters-ws/react-seo/core';
|
|
697
|
+
*
|
|
698
|
+
* const siteConfig = { name: 'My Site', url: 'https://mysite.com', ... };
|
|
699
|
+
*
|
|
700
|
+
* export async function generateMetadata({ params }) {
|
|
701
|
+
* const article = await fetchArticle(params.slug);
|
|
702
|
+
* const { metadata } = generateArticleMetadata(article, siteConfig);
|
|
703
|
+
* return metadata;
|
|
704
|
+
* }
|
|
705
|
+
*
|
|
706
|
+
* export default async function ArticlePage({ params }) {
|
|
707
|
+
* const article = await fetchArticle(params.slug);
|
|
708
|
+
* const { schemas } = generateArticleMetadata(article, siteConfig);
|
|
709
|
+
*
|
|
710
|
+
* return (
|
|
711
|
+
* <>
|
|
712
|
+
* <JsonLd schema={schemas} />
|
|
713
|
+
* <article>...</article>
|
|
714
|
+
* </>
|
|
715
|
+
* );
|
|
716
|
+
* }
|
|
717
|
+
* ```
|
|
718
|
+
*/
|
|
719
|
+
declare function generateArticleMetadata(article: ArticleMetadataInput, config: SiteConfig): ArticleMetadataResult;
|
|
720
|
+
|
|
721
|
+
export { type ArticleMetadataInput as A, type BreadcrumbItem as B, JsonLd as J, type ProductMetadataInput as P, type SiteConfig as S, type SEOData as a, type ArticleMetadataResult as b, type JsonLdProps as c, type ProductMetadataResult as d, generateArticleSchema as e, generateBookSchema as f, generateArticleMetadata as g, generateBreadcrumbSchema as h, generateEventSchema as i, generateFAQSchema as j, generateLocalBusinessSchema as k, generateMovieSchema as l, generateOrganizationSchema as m, generatePaginatedTitle as n, generatePaginationLinks as o, generatePodcastEpisodeSchema as p, generatePodcastSchema as q, generateProductMetadata as r, generateProductSchema as s, generateSoftwareSchema as t, generateVideoSchema as u, generateWebSiteSchema as v, toNextMetadata as w };
|