@zoyth/simple-site-framework 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +572 -0
  3. package/bin/create-simple-site.js +390 -0
  4. package/bin/simple-site.js +664 -0
  5. package/dist/client.js +135 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/client.mjs +107 -0
  8. package/dist/client.mjs.map +1 -0
  9. package/dist/components/index.d.mts +3936 -0
  10. package/dist/components/index.d.ts +3936 -0
  11. package/dist/components/index.js +38265 -0
  12. package/dist/components/index.js.map +1 -0
  13. package/dist/components/index.mjs +38173 -0
  14. package/dist/components/index.mjs.map +1 -0
  15. package/dist/config/index.d.mts +298 -0
  16. package/dist/config/index.d.ts +298 -0
  17. package/dist/config/index.js +19 -0
  18. package/dist/config/index.js.map +1 -0
  19. package/dist/config/index.mjs +1 -0
  20. package/dist/config/index.mjs.map +1 -0
  21. package/dist/index.d.mts +2184 -0
  22. package/dist/index.d.ts +2184 -0
  23. package/dist/index.js +1713 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/index.mjs +1605 -0
  26. package/dist/index.mjs.map +1 -0
  27. package/dist/lib/i18n/index.js +665 -0
  28. package/dist/lib/i18n/index.js.map +1 -0
  29. package/dist/lib/i18n/index.mjs +621 -0
  30. package/dist/lib/i18n/index.mjs.map +1 -0
  31. package/docs/DOCUMENTATION-STRUCTURE.md +1156 -0
  32. package/docs/EXPORTS.md +125 -0
  33. package/docs/PERFORMANCE.md +757 -0
  34. package/docs/POLICY-PAGES.md +867 -0
  35. package/docs/ROADMAP.md +334 -0
  36. package/docs/SEO.md +455 -0
  37. package/docs/SITEMAP.md +708 -0
  38. package/docs/STRUCTURED-DATA.md +671 -0
  39. package/docs/accessibility/common-patterns.md +529 -0
  40. package/docs/accessibility/keyboard-navigation.md +263 -0
  41. package/docs/accessibility/overview.md +122 -0
  42. package/docs/accessibility/screen-readers.md +311 -0
  43. package/docs/accessibility/wcag-compliance.md +159 -0
  44. package/docs/api/README.md +164 -0
  45. package/docs/api/components/Accessibility.md +356 -0
  46. package/docs/api/components/Button.md +240 -0
  47. package/docs/api/components/HeroSection.md +306 -0
  48. package/docs/architecture/decisions.md +449 -0
  49. package/docs/components/AnalyticsTracker.md +58 -0
  50. package/docs/components/AnimatedCounter.md +48 -0
  51. package/docs/components/AnimatedSection.md +56 -0
  52. package/docs/components/BlogCard.md +42 -0
  53. package/docs/components/Checkbox.md +56 -0
  54. package/docs/components/CodeBlock.md +52 -0
  55. package/docs/components/ComparisonTable.md +40 -0
  56. package/docs/components/ComponentDemo.md +38 -0
  57. package/docs/components/CountdownTimer.md +51 -0
  58. package/docs/components/ExitIntentModal.md +56 -0
  59. package/docs/components/FAQAccordion.md +66 -0
  60. package/docs/components/FeaturesGrid.md +55 -0
  61. package/docs/components/FileUpload.md +54 -0
  62. package/docs/components/I18nMetaTags.md +55 -0
  63. package/docs/components/Icon.md +53 -0
  64. package/docs/components/LazySection.md +46 -0
  65. package/docs/components/LiveProof.md +53 -0
  66. package/docs/components/LoadingSpinner.md +46 -0
  67. package/docs/components/MultiStepForm.md +48 -0
  68. package/docs/components/PolicyLayout.md +55 -0
  69. package/docs/components/PricingTable.md +49 -0
  70. package/docs/components/Radio.md +59 -0
  71. package/docs/components/SEOMetaTags.md +58 -0
  72. package/docs/components/ScriptInjector.md +50 -0
  73. package/docs/components/Select.md +72 -0
  74. package/docs/components/Skeleton.md +47 -0
  75. package/docs/components/StatsSection.md +48 -0
  76. package/docs/components/StickyBar.md +62 -0
  77. package/docs/components/StructuredData.md +99 -0
  78. package/docs/components/StyleGuide.md +46 -0
  79. package/docs/components/TableOfContents.md +47 -0
  80. package/docs/components/TestimonialCarousel.md +42 -0
  81. package/docs/components/Timeline.md +51 -0
  82. package/docs/components/Toast.md +59 -0
  83. package/docs/components/TrackedLink.md +62 -0
  84. package/docs/components/TrustBadges.md +44 -0
  85. package/docs/components/conversion/MobileCTA.md +363 -0
  86. package/docs/components/forms/ContactForm.md +75 -0
  87. package/docs/components/forms/FormField.md +74 -0
  88. package/docs/components/layout/Footer.md +601 -0
  89. package/docs/components/layout/Header.md +549 -0
  90. package/docs/components/layout/LanguageSelector.md +54 -0
  91. package/docs/components/layout/LanguageSwitcher.md +24 -0
  92. package/docs/components/overview.md +447 -0
  93. package/docs/components/sections/AboutSection.md +48 -0
  94. package/docs/components/sections/CTASection.md +596 -0
  95. package/docs/components/sections/CaseStudySection.md +47 -0
  96. package/docs/components/sections/ContactSection.md +599 -0
  97. package/docs/components/sections/FeatureSection.md +44 -0
  98. package/docs/components/sections/HeroSection.md +404 -0
  99. package/docs/components/sections/LogosSection.md +47 -0
  100. package/docs/components/sections/PersonalTaxesSection.md +23 -0
  101. package/docs/components/sections/RecruitingSection.md +23 -0
  102. package/docs/components/sections/SecurePortalSection.md +23 -0
  103. package/docs/components/sections/ServicePageLayout.md +52 -0
  104. package/docs/components/sections/ServicesSection.md +49 -0
  105. package/docs/components/sections/TestimonialSection.md +44 -0
  106. package/docs/components/sections/WhyChooseUsSection.md +54 -0
  107. package/docs/components/ui/Breadcrumb.md +70 -0
  108. package/docs/components/ui/Button.md +514 -0
  109. package/docs/components/ui/Card.md +501 -0
  110. package/docs/components/ui/Input.md +54 -0
  111. package/docs/components/ui/MobileLinks.md +43 -0
  112. package/docs/components/ui/Modal.md +60 -0
  113. package/docs/components/ui/Tabs.md +62 -0
  114. package/docs/components/ui/Textarea.md +52 -0
  115. package/docs/core-concepts/configuration-driven.md +552 -0
  116. package/docs/core-concepts/overview.md +351 -0
  117. package/docs/features/accessibility/README.md +73 -0
  118. package/docs/features/accessibility/aria-support.md +177 -0
  119. package/docs/features/accessibility/color-contrast.md +155 -0
  120. package/docs/features/accessibility/focus-management.md +187 -0
  121. package/docs/features/accessibility/testing.md +196 -0
  122. package/docs/features/analytics/README.md +51 -0
  123. package/docs/features/analytics/ab-testing.md +171 -0
  124. package/docs/features/analytics/conversion-tracking.md +207 -0
  125. package/docs/features/analytics/custom-events.md +219 -0
  126. package/docs/features/analytics/privacy.md +198 -0
  127. package/docs/features/analytics/setup.md +114 -0
  128. package/docs/features/analytics/tracking-events.md +224 -0
  129. package/docs/features/i18n/README.md +51 -0
  130. package/docs/features/i18n/best-practices.md +273 -0
  131. package/docs/features/i18n/configuration.md +84 -0
  132. package/docs/features/i18n/formatting.md +133 -0
  133. package/docs/features/i18n/locale-detection.md +122 -0
  134. package/docs/features/i18n/routing.md +99 -0
  135. package/docs/features/i18n/rtl-support.md +191 -0
  136. package/docs/features/i18n/translations.md +129 -0
  137. package/docs/features/internationalization.md +595 -0
  138. package/docs/features/performance/README.md +77 -0
  139. package/docs/features/performance/bundle-size.md +134 -0
  140. package/docs/features/performance/caching.md +131 -0
  141. package/docs/features/performance/code-splitting.md +121 -0
  142. package/docs/features/performance/image-optimization.md +110 -0
  143. package/docs/features/performance/lazy-loading.md +92 -0
  144. package/docs/features/performance/monitoring.md +148 -0
  145. package/docs/features/seo/README.md +51 -0
  146. package/docs/features/seo/best-practices.md +184 -0
  147. package/docs/features/seo/canonical-urls.md +182 -0
  148. package/docs/features/seo/meta-tags.md +126 -0
  149. package/docs/features/seo/open-graph.md +166 -0
  150. package/docs/features/seo/robots-txt.md +146 -0
  151. package/docs/features/seo/sitemaps.md +162 -0
  152. package/docs/features/seo/structured-data.md +166 -0
  153. package/docs/getting-started/installation.md +292 -0
  154. package/docs/getting-started/introduction.md +195 -0
  155. package/docs/getting-started/quick-start.md +460 -0
  156. package/docs/guides/analytics-setup.md +616 -0
  157. package/docs/i18n/CONFIGURATION.md +353 -0
  158. package/docs/i18n/EXAMPLES.md +402 -0
  159. package/docs/i18n/MIGRATION.md +260 -0
  160. package/docs/i18n/SEO.md +392 -0
  161. package/docs/i18n/STATIC-GENERATION-FIX.md +71 -0
  162. package/docs/migration/changelog.md +136 -0
  163. package/docs/migration/overview.md +233 -0
  164. package/docs/recipes/adding-animations.md +475 -0
  165. package/docs/recipes/forms-with-validation.md +393 -0
  166. package/package.json +152 -0
@@ -0,0 +1,671 @@
1
+ # Structured Data (JSON-LD) Guide
2
+
3
+ Complete guide to implementing schema.org structured data with JSON-LD for rich search results.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Quick Start](#quick-start)
9
+ - [Schema Types](#schema-types)
10
+ - [Helper Functions](#helper-functions)
11
+ - [StructuredData Component](#structureddata-component)
12
+ - [Common Patterns](#common-patterns)
13
+ - [Testing](#testing)
14
+ - [Best Practices](#best-practices)
15
+
16
+ ## Overview
17
+
18
+ Structured data helps search engines understand your content better, enabling:
19
+
20
+ - **Rich snippets**: Enhanced search results with ratings, prices, images
21
+ - **Knowledge panels**: Dedicated information boxes in search results
22
+ - **Voice search**: Better answers for voice assistants
23
+ - **Click-through rates**: More attractive search results = more clicks
24
+
25
+ The framework provides:
26
+ - Type-safe schema.org interfaces
27
+ - Helper functions for creating structured data
28
+ - `<StructuredData>` component for rendering JSON-LD
29
+
30
+ ## Quick Start
31
+
32
+ ### 1. Organization Schema (Recommended for All Sites)
33
+
34
+ Add this to your root layout to tell search engines about your business:
35
+
36
+ ```tsx
37
+ import { StructuredData } from 'simple-site-framework/components';
38
+ import { createOrganization } from 'simple-site-framework/lib/seo/structured-data';
39
+
40
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
41
+ const organization = createOrganization({
42
+ name: 'Acme Inc',
43
+ url: 'https://acme.com',
44
+ logo: 'https://acme.com/logo.png',
45
+ description: 'Leading email marketing platform',
46
+ email: 'hello@acme.com',
47
+ telephone: '+1-555-1234',
48
+ sameAs: [
49
+ 'https://twitter.com/acme',
50
+ 'https://facebook.com/acme',
51
+ 'https://linkedin.com/company/acme'
52
+ ],
53
+ address: {
54
+ '@type': 'PostalAddress',
55
+ streetAddress: '123 Main St',
56
+ addressLocality: 'San Francisco',
57
+ addressRegion: 'CA',
58
+ postalCode: '94102',
59
+ addressCountry: 'US'
60
+ }
61
+ });
62
+
63
+ return (
64
+ <html>
65
+ <head>
66
+ <StructuredData data={organization} />
67
+ </head>
68
+ <body>{children}</body>
69
+ </html>
70
+ );
71
+ }
72
+ ```
73
+
74
+ ### 2. WebSite Schema with Search
75
+
76
+ Enable Google's sitelinks search box:
77
+
78
+ ```tsx
79
+ import { createWebSite } from 'simple-site-framework/lib/seo/structured-data';
80
+
81
+ const website = createWebSite({
82
+ name: 'Acme',
83
+ url: 'https://acme.com',
84
+ description: 'Email marketing platform',
85
+ searchUrlTemplate: 'https://acme.com/search?q={search_term_string}'
86
+ });
87
+
88
+ <StructuredData data={website} />
89
+ ```
90
+
91
+ ### 3. Multiple Schemas on One Page
92
+
93
+ Combine multiple structured data objects:
94
+
95
+ ```tsx
96
+ import { StructuredData } from 'simple-site-framework/components';
97
+ import {
98
+ createOrganization,
99
+ createWebSite,
100
+ createBreadcrumbList
101
+ } from 'simple-site-framework/lib/seo/structured-data';
102
+
103
+ export default function Page() {
104
+ const data = [
105
+ createOrganization({ name: 'Acme', url: 'https://acme.com' }),
106
+ createWebSite({ name: 'Acme', url: 'https://acme.com' }),
107
+ createBreadcrumbList([
108
+ { name: 'Home', url: 'https://acme.com' },
109
+ { name: 'Products', url: 'https://acme.com/products' }
110
+ ])
111
+ ];
112
+
113
+ return (
114
+ <>
115
+ <StructuredData data={data} />
116
+ <main>...</main>
117
+ </>
118
+ );
119
+ }
120
+ ```
121
+
122
+ ## Schema Types
123
+
124
+ ### Organization
125
+
126
+ Describe your company/organization:
127
+
128
+ ```tsx
129
+ import { createOrganization } from 'simple-site-framework/lib/seo/structured-data';
130
+
131
+ const org = createOrganization({
132
+ name: 'Acme Inc',
133
+ url: 'https://acme.com',
134
+ logo: 'https://acme.com/logo.png',
135
+ description: 'Email marketing platform',
136
+ email: 'hello@acme.com',
137
+ telephone: '+1-555-1234',
138
+
139
+ // Address
140
+ address: {
141
+ '@type': 'PostalAddress',
142
+ streetAddress: '123 Main St',
143
+ addressLocality: 'San Francisco',
144
+ addressRegion: 'CA',
145
+ postalCode: '94102',
146
+ addressCountry: 'US'
147
+ },
148
+
149
+ // Social media profiles
150
+ sameAs: [
151
+ 'https://twitter.com/acme',
152
+ 'https://facebook.com/acme',
153
+ 'https://linkedin.com/company/acme',
154
+ 'https://github.com/acme'
155
+ ],
156
+
157
+ // Contact points
158
+ contactPoint: [
159
+ {
160
+ '@type': 'ContactPoint',
161
+ telephone: '+1-555-SALES',
162
+ email: 'sales@acme.com',
163
+ contactType: 'sales',
164
+ availableLanguage: ['English', 'French'],
165
+ areaServed: ['US', 'CA']
166
+ },
167
+ {
168
+ '@type': 'ContactPoint',
169
+ telephone: '+1-555-SUPPORT',
170
+ email: 'support@acme.com',
171
+ contactType: 'customer service',
172
+ availableLanguage: ['English', 'French', 'Spanish']
173
+ }
174
+ ],
175
+
176
+ // Founders
177
+ founders: [
178
+ {
179
+ '@type': 'Person',
180
+ name: 'Jane Doe',
181
+ jobTitle: 'CEO',
182
+ image: 'https://acme.com/team/jane.jpg'
183
+ }
184
+ ],
185
+
186
+ foundingDate: '2020-01-15'
187
+ });
188
+ ```
189
+
190
+ ### WebSite
191
+
192
+ Define your website with optional search functionality:
193
+
194
+ ```tsx
195
+ import { createWebSite } from 'simple-site-framework/lib/seo/structured-data';
196
+
197
+ const website = createWebSite({
198
+ name: 'Acme',
199
+ url: 'https://acme.com',
200
+ description: 'The best email marketing platform',
201
+
202
+ // Enable Google's sitelinks search box
203
+ searchUrlTemplate: 'https://acme.com/search?q={search_term_string}',
204
+
205
+ publisher: createOrganization({
206
+ name: 'Acme Inc',
207
+ url: 'https://acme.com'
208
+ })
209
+ });
210
+ ```
211
+
212
+ ### Product
213
+
214
+ Product pages for e-commerce or SaaS plans:
215
+
216
+ ```tsx
217
+ import { createProduct } from 'simple-site-framework/lib/seo/structured-data';
218
+
219
+ const product = createProduct({
220
+ name: 'Premium Email Plan',
221
+ description: 'Unlimited emails, advanced automation, priority support',
222
+ image: [
223
+ 'https://acme.com/images/premium-1.jpg',
224
+ 'https://acme.com/images/premium-2.jpg'
225
+ ],
226
+
227
+ brand: createOrganization({
228
+ name: 'Acme',
229
+ url: 'https://acme.com'
230
+ }),
231
+
232
+ offers: {
233
+ '@type': 'Offer',
234
+ price: '99.00',
235
+ priceCurrency: 'USD',
236
+ priceValidUntil: '2024-12-31',
237
+ availability: 'InStock',
238
+ url: 'https://acme.com/pricing/premium',
239
+ seller: createOrganization({
240
+ name: 'Acme Inc',
241
+ url: 'https://acme.com'
242
+ })
243
+ },
244
+
245
+ aggregateRating: {
246
+ '@type': 'AggregateRating',
247
+ ratingValue: 4.8,
248
+ reviewCount: 127,
249
+ bestRating: 5,
250
+ worstRating: 1
251
+ },
252
+
253
+ review: [
254
+ {
255
+ '@type': 'Review',
256
+ author: {
257
+ '@type': 'Person',
258
+ name: 'John Smith'
259
+ },
260
+ datePublished: '2024-01-15',
261
+ reviewBody: 'Excellent email platform! Easy to use and great support.',
262
+ reviewRating: {
263
+ '@type': 'Rating',
264
+ ratingValue: 5,
265
+ bestRating: 5
266
+ }
267
+ }
268
+ ]
269
+ });
270
+ ```
271
+
272
+ ### FAQ Page
273
+
274
+ FAQ pages with questions and answers:
275
+
276
+ ```tsx
277
+ import { createFAQPage } from 'simple-site-framework/lib/seo/structured-data';
278
+
279
+ const faq = createFAQPage([
280
+ {
281
+ question: 'What is your refund policy?',
282
+ answer: 'We offer a 30-day money-back guarantee on all plans. No questions asked.'
283
+ },
284
+ {
285
+ question: 'Do you offer customer support?',
286
+ answer: 'Yes! We provide 24/7 email and chat support to all customers, plus phone support for Premium plans.'
287
+ },
288
+ {
289
+ question: 'Can I cancel anytime?',
290
+ answer: 'Absolutely. Cancel your subscription anytime from your account dashboard. No cancellation fees.'
291
+ },
292
+ {
293
+ question: 'Is my data secure?',
294
+ answer: 'Yes. We use bank-level encryption (AES-256) and are SOC 2 Type II certified.'
295
+ }
296
+ ]);
297
+
298
+ <StructuredData data={faq} />
299
+ ```
300
+
301
+ ### Article / Blog Post
302
+
303
+ Blog posts and articles:
304
+
305
+ ```tsx
306
+ import { createArticle } from 'simple-site-framework/lib/seo/structured-data';
307
+
308
+ const article = createArticle({
309
+ type: 'BlogPosting', // or 'Article' or 'NewsArticle'
310
+ headline: '10 Email Marketing Tips to Triple Your ROI',
311
+ description: 'Learn proven strategies to boost your email marketing performance',
312
+ image: [
313
+ 'https://acme.com/blog/email-tips-hero.jpg',
314
+ 'https://acme.com/blog/email-tips-square.jpg'
315
+ ],
316
+
317
+ author: {
318
+ '@type': 'Person',
319
+ name: 'Jane Doe',
320
+ url: 'https://acme.com/authors/jane-doe',
321
+ image: 'https://acme.com/authors/jane.jpg',
322
+ jobTitle: 'Head of Marketing'
323
+ },
324
+
325
+ publisher: createOrganization({
326
+ name: 'Acme Blog',
327
+ url: 'https://acme.com/blog',
328
+ logo: 'https://acme.com/logo.png'
329
+ }),
330
+
331
+ datePublished: '2024-01-15T10:00:00Z',
332
+ dateModified: '2024-01-20T14:30:00Z',
333
+ mainEntityOfPage: 'https://acme.com/blog/email-marketing-tips'
334
+ });
335
+ ```
336
+
337
+ ### Breadcrumbs
338
+
339
+ Navigation breadcrumbs for better site structure:
340
+
341
+ ```tsx
342
+ import { createBreadcrumbList } from 'simple-site-framework/lib/seo/structured-data';
343
+
344
+ const breadcrumbs = createBreadcrumbList([
345
+ { name: 'Home', url: 'https://acme.com' },
346
+ { name: 'Blog', url: 'https://acme.com/blog' },
347
+ { name: 'Email Marketing', url: 'https://acme.com/blog/category/email-marketing' },
348
+ { name: '10 Email Tips' } // Current page (no URL)
349
+ ]);
350
+
351
+ <StructuredData data={breadcrumbs} />
352
+ ```
353
+
354
+ ## Helper Functions
355
+
356
+ ### createOrganization()
357
+
358
+ ```tsx
359
+ function createOrganization(data: Omit<Organization, '@type'>): Organization
360
+ ```
361
+
362
+ ### createWebSite()
363
+
364
+ ```tsx
365
+ function createWebSite(data: {
366
+ name: string;
367
+ url: string;
368
+ description?: string;
369
+ publisher?: Organization;
370
+ searchUrlTemplate?: string;
371
+ }): WebSite
372
+ ```
373
+
374
+ ### createProduct()
375
+
376
+ ```tsx
377
+ function createProduct(data: Omit<Product, '@type'>): Product
378
+ ```
379
+
380
+ ### createFAQPage()
381
+
382
+ ```tsx
383
+ function createFAQPage(
384
+ faqs: Array<{ question: string; answer: string }>
385
+ ): FAQPage
386
+ ```
387
+
388
+ ### createArticle()
389
+
390
+ ```tsx
391
+ function createArticle(data: {
392
+ headline: string;
393
+ description?: string;
394
+ image?: string | string[];
395
+ author: Person | string;
396
+ publisher: Organization;
397
+ datePublished: string;
398
+ dateModified?: string;
399
+ mainEntityOfPage?: string;
400
+ type?: 'Article' | 'BlogPosting' | 'NewsArticle';
401
+ }): Article
402
+ ```
403
+
404
+ ### createBreadcrumbList()
405
+
406
+ ```tsx
407
+ function createBreadcrumbList(
408
+ items: Array<{ name: string; url?: string }>
409
+ ): BreadcrumbList
410
+ ```
411
+
412
+ ### serializeStructuredData()
413
+
414
+ Manually serialize structured data to JSON-LD string:
415
+
416
+ ```tsx
417
+ function serializeStructuredData(data: Thing | Thing[]): string
418
+ ```
419
+
420
+ ## StructuredData Component
421
+
422
+ ```tsx
423
+ import { StructuredData } from 'simple-site-framework/components';
424
+
425
+ interface StructuredDataProps {
426
+ /** Structured data object or array of objects */
427
+ data: Thing | Thing[];
428
+ }
429
+ ```
430
+
431
+ The component renders a `<script type="application/ld+json">` tag with your structured data.
432
+
433
+ ## Common Patterns
434
+
435
+ ### Homepage
436
+
437
+ ```tsx
438
+ import { StructuredData } from 'simple-site-framework/components';
439
+ import { createOrganization, createWebSite } from 'simple-site-framework/lib/seo/structured-data';
440
+
441
+ export default function HomePage() {
442
+ const data = [
443
+ createOrganization({
444
+ name: 'Acme Inc',
445
+ url: 'https://acme.com',
446
+ logo: 'https://acme.com/logo.png',
447
+ sameAs: ['https://twitter.com/acme']
448
+ }),
449
+ createWebSite({
450
+ name: 'Acme',
451
+ url: 'https://acme.com',
452
+ searchUrlTemplate: 'https://acme.com/search?q={search_term_string}'
453
+ })
454
+ ];
455
+
456
+ return (
457
+ <>
458
+ <StructuredData data={data} />
459
+ <main>...</main>
460
+ </>
461
+ );
462
+ }
463
+ ```
464
+
465
+ ### Product/Pricing Page
466
+
467
+ ```tsx
468
+ const product = createProduct({
469
+ name: 'Premium Plan',
470
+ description: 'Full-featured email marketing',
471
+ offers: {
472
+ '@type': 'Offer',
473
+ price: '99.00',
474
+ priceCurrency: 'USD',
475
+ availability: 'InStock'
476
+ }
477
+ });
478
+
479
+ const breadcrumbs = createBreadcrumbList([
480
+ { name: 'Home', url: 'https://acme.com' },
481
+ { name: 'Pricing', url: 'https://acme.com/pricing' },
482
+ { name: 'Premium Plan' }
483
+ ]);
484
+
485
+ <StructuredData data={[product, breadcrumbs]} />
486
+ ```
487
+
488
+ ### Blog Post
489
+
490
+ ```tsx
491
+ const article = createArticle({
492
+ headline: 'Blog Post Title',
493
+ author: { '@type': 'Person', name: 'Jane Doe' },
494
+ publisher: createOrganization({ name: 'Acme Blog' }),
495
+ datePublished: '2024-01-15T10:00:00Z',
496
+ image: 'https://acme.com/blog/image.jpg'
497
+ });
498
+
499
+ const breadcrumbs = createBreadcrumbList([
500
+ { name: 'Home', url: 'https://acme.com' },
501
+ { name: 'Blog', url: 'https://acme.com/blog' },
502
+ { name: 'Post Title' }
503
+ ]);
504
+
505
+ <StructuredData data={[article, breadcrumbs]} />
506
+ ```
507
+
508
+ ### FAQ Page
509
+
510
+ ```tsx
511
+ const faq = createFAQPage([
512
+ { question: 'Q1?', answer: 'A1' },
513
+ { question: 'Q2?', answer: 'A2' }
514
+ ]);
515
+
516
+ <StructuredData data={faq} />
517
+ ```
518
+
519
+ ## Testing
520
+
521
+ ### Google's Rich Results Test
522
+
523
+ 1. Go to: https://search.google.com/test/rich-results
524
+ 2. Enter your URL or paste HTML
525
+ 3. Check for errors and warnings
526
+ 4. Preview how it appears in search
527
+
528
+ ### Schema.org Validator
529
+
530
+ 1. Go to: https://validator.schema.org/
531
+ 2. Paste your JSON-LD
532
+ 3. Verify structure matches schema.org spec
533
+
534
+ ### Manual Inspection
535
+
536
+ ```tsx
537
+ // View rendered JSON-LD in browser DevTools
538
+ document.querySelector('script[type="application/ld+json"]').textContent
539
+ ```
540
+
541
+ ## Best Practices
542
+
543
+ ### 1. Use Absolute URLs
544
+
545
+ Always use absolute URLs (https://...) never relative (/page):
546
+
547
+ ```tsx
548
+ // ✅ Good
549
+ image: 'https://acme.com/image.jpg'
550
+ url: 'https://acme.com/page'
551
+
552
+ // ❌ Bad
553
+ image: '/image.jpg'
554
+ url: '/page'
555
+ ```
556
+
557
+ ### 2. Match Visible Content
558
+
559
+ Structured data should match what users see on the page:
560
+
561
+ ```tsx
562
+ // ✅ Good - Matches H1 on page
563
+ headline: '10 Email Marketing Tips'
564
+
565
+ // ❌ Bad - Different from H1
566
+ headline: 'Amazing Email Tips You Won\'t Believe!'
567
+ ```
568
+
569
+ ### 3. Use ISO 8601 Dates
570
+
571
+ ```tsx
572
+ // ✅ Good
573
+ datePublished: '2024-01-15T10:00:00Z'
574
+ datePublished: '2024-01-15'
575
+
576
+ // ❌ Bad
577
+ datePublished: 'January 15, 2024'
578
+ datePublished: '01/15/2024'
579
+ ```
580
+
581
+ ### 4. Multiple Images
582
+
583
+ Provide multiple image sizes for better rich results:
584
+
585
+ ```tsx
586
+ image: [
587
+ 'https://acme.com/image-1200x630.jpg', // OG image (1.91:1)
588
+ 'https://acme.com/image-800x800.jpg', // Square (1:1)
589
+ 'https://acme.com/image-1600x900.jpg' // 16:9
590
+ ]
591
+ ```
592
+
593
+ ### 5. Complete Publisher Info
594
+
595
+ Articles require complete publisher with logo:
596
+
597
+ ```tsx
598
+ publisher: {
599
+ '@type': 'Organization',
600
+ name: 'Acme Blog',
601
+ logo: 'https://acme.com/logo.png' // Required
602
+ }
603
+ ```
604
+
605
+ ### 6. Rating Values
606
+
607
+ Use numeric values with proper ranges:
608
+
609
+ ```tsx
610
+ // ✅ Good
611
+ aggregateRating: {
612
+ '@type': 'AggregateRating',
613
+ ratingValue: 4.8,
614
+ bestRating: 5,
615
+ worstRating: 1,
616
+ reviewCount: 127
617
+ }
618
+
619
+ // ❌ Bad - Missing context
620
+ aggregateRating: {
621
+ '@type': 'AggregateRating',
622
+ ratingValue: 4.8
623
+ }
624
+ ```
625
+
626
+ ### 7. Avoid Spam
627
+
628
+ Don't add structured data for content not on the page:
629
+
630
+ ```tsx
631
+ // ❌ Bad - Review not visible on page
632
+ review: [{
633
+ author: 'Fake Reviewer',
634
+ reviewBody: 'Amazing product!',
635
+ reviewRating: { ratingValue: 5 }
636
+ }]
637
+ ```
638
+
639
+ ### 8. Test Before Deploy
640
+
641
+ Always test with Google's Rich Results Test before deploying.
642
+
643
+ ### 9. Monitor Search Console
644
+
645
+ Check Google Search Console → Enhancements for errors and warnings.
646
+
647
+ ### 10. Keep It Updated
648
+
649
+ Update `dateModified` when content changes significantly.
650
+
651
+ ## Checklist
652
+
653
+ - [ ] Organization schema on all pages
654
+ - [ ] WebSite schema with search action (homepage)
655
+ - [ ] Product schema on product/pricing pages
656
+ - [ ] Article schema on blog posts
657
+ - [ ] FAQ schema on FAQ pages
658
+ - [ ] Breadcrumbs on deep pages
659
+ - [ ] All URLs are absolute (https://)
660
+ - [ ] Dates in ISO 8601 format
661
+ - [ ] Images are high quality (min 1200px wide)
662
+ - [ ] Tested with Google Rich Results Test
663
+ - [ ] No errors in Search Console
664
+
665
+ ## Resources
666
+
667
+ - [Schema.org Documentation](https://schema.org/)
668
+ - [Google Search Central - Structured Data](https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data)
669
+ - [Google Rich Results Test](https://search.google.com/test/rich-results)
670
+ - [Schema.org Validator](https://validator.schema.org/)
671
+ - [JSON-LD Playground](https://json-ld.org/playground/)