@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.
- package/LICENSE +21 -0
- package/README.md +572 -0
- package/bin/create-simple-site.js +390 -0
- package/bin/simple-site.js +664 -0
- package/dist/client.js +135 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +107 -0
- package/dist/client.mjs.map +1 -0
- package/dist/components/index.d.mts +3936 -0
- package/dist/components/index.d.ts +3936 -0
- package/dist/components/index.js +38265 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +38173 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config/index.d.mts +298 -0
- package/dist/config/index.d.ts +298 -0
- package/dist/config/index.js +19 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.mjs +1 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/index.d.mts +2184 -0
- package/dist/index.d.ts +2184 -0
- package/dist/index.js +1713 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1605 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/i18n/index.js +665 -0
- package/dist/lib/i18n/index.js.map +1 -0
- package/dist/lib/i18n/index.mjs +621 -0
- package/dist/lib/i18n/index.mjs.map +1 -0
- package/docs/DOCUMENTATION-STRUCTURE.md +1156 -0
- package/docs/EXPORTS.md +125 -0
- package/docs/PERFORMANCE.md +757 -0
- package/docs/POLICY-PAGES.md +867 -0
- package/docs/ROADMAP.md +334 -0
- package/docs/SEO.md +455 -0
- package/docs/SITEMAP.md +708 -0
- package/docs/STRUCTURED-DATA.md +671 -0
- package/docs/accessibility/common-patterns.md +529 -0
- package/docs/accessibility/keyboard-navigation.md +263 -0
- package/docs/accessibility/overview.md +122 -0
- package/docs/accessibility/screen-readers.md +311 -0
- package/docs/accessibility/wcag-compliance.md +159 -0
- package/docs/api/README.md +164 -0
- package/docs/api/components/Accessibility.md +356 -0
- package/docs/api/components/Button.md +240 -0
- package/docs/api/components/HeroSection.md +306 -0
- package/docs/architecture/decisions.md +449 -0
- package/docs/components/AnalyticsTracker.md +58 -0
- package/docs/components/AnimatedCounter.md +48 -0
- package/docs/components/AnimatedSection.md +56 -0
- package/docs/components/BlogCard.md +42 -0
- package/docs/components/Checkbox.md +56 -0
- package/docs/components/CodeBlock.md +52 -0
- package/docs/components/ComparisonTable.md +40 -0
- package/docs/components/ComponentDemo.md +38 -0
- package/docs/components/CountdownTimer.md +51 -0
- package/docs/components/ExitIntentModal.md +56 -0
- package/docs/components/FAQAccordion.md +66 -0
- package/docs/components/FeaturesGrid.md +55 -0
- package/docs/components/FileUpload.md +54 -0
- package/docs/components/I18nMetaTags.md +55 -0
- package/docs/components/Icon.md +53 -0
- package/docs/components/LazySection.md +46 -0
- package/docs/components/LiveProof.md +53 -0
- package/docs/components/LoadingSpinner.md +46 -0
- package/docs/components/MultiStepForm.md +48 -0
- package/docs/components/PolicyLayout.md +55 -0
- package/docs/components/PricingTable.md +49 -0
- package/docs/components/Radio.md +59 -0
- package/docs/components/SEOMetaTags.md +58 -0
- package/docs/components/ScriptInjector.md +50 -0
- package/docs/components/Select.md +72 -0
- package/docs/components/Skeleton.md +47 -0
- package/docs/components/StatsSection.md +48 -0
- package/docs/components/StickyBar.md +62 -0
- package/docs/components/StructuredData.md +99 -0
- package/docs/components/StyleGuide.md +46 -0
- package/docs/components/TableOfContents.md +47 -0
- package/docs/components/TestimonialCarousel.md +42 -0
- package/docs/components/Timeline.md +51 -0
- package/docs/components/Toast.md +59 -0
- package/docs/components/TrackedLink.md +62 -0
- package/docs/components/TrustBadges.md +44 -0
- package/docs/components/conversion/MobileCTA.md +363 -0
- package/docs/components/forms/ContactForm.md +75 -0
- package/docs/components/forms/FormField.md +74 -0
- package/docs/components/layout/Footer.md +601 -0
- package/docs/components/layout/Header.md +549 -0
- package/docs/components/layout/LanguageSelector.md +54 -0
- package/docs/components/layout/LanguageSwitcher.md +24 -0
- package/docs/components/overview.md +447 -0
- package/docs/components/sections/AboutSection.md +48 -0
- package/docs/components/sections/CTASection.md +596 -0
- package/docs/components/sections/CaseStudySection.md +47 -0
- package/docs/components/sections/ContactSection.md +599 -0
- package/docs/components/sections/FeatureSection.md +44 -0
- package/docs/components/sections/HeroSection.md +404 -0
- package/docs/components/sections/LogosSection.md +47 -0
- package/docs/components/sections/PersonalTaxesSection.md +23 -0
- package/docs/components/sections/RecruitingSection.md +23 -0
- package/docs/components/sections/SecurePortalSection.md +23 -0
- package/docs/components/sections/ServicePageLayout.md +52 -0
- package/docs/components/sections/ServicesSection.md +49 -0
- package/docs/components/sections/TestimonialSection.md +44 -0
- package/docs/components/sections/WhyChooseUsSection.md +54 -0
- package/docs/components/ui/Breadcrumb.md +70 -0
- package/docs/components/ui/Button.md +514 -0
- package/docs/components/ui/Card.md +501 -0
- package/docs/components/ui/Input.md +54 -0
- package/docs/components/ui/MobileLinks.md +43 -0
- package/docs/components/ui/Modal.md +60 -0
- package/docs/components/ui/Tabs.md +62 -0
- package/docs/components/ui/Textarea.md +52 -0
- package/docs/core-concepts/configuration-driven.md +552 -0
- package/docs/core-concepts/overview.md +351 -0
- package/docs/features/accessibility/README.md +73 -0
- package/docs/features/accessibility/aria-support.md +177 -0
- package/docs/features/accessibility/color-contrast.md +155 -0
- package/docs/features/accessibility/focus-management.md +187 -0
- package/docs/features/accessibility/testing.md +196 -0
- package/docs/features/analytics/README.md +51 -0
- package/docs/features/analytics/ab-testing.md +171 -0
- package/docs/features/analytics/conversion-tracking.md +207 -0
- package/docs/features/analytics/custom-events.md +219 -0
- package/docs/features/analytics/privacy.md +198 -0
- package/docs/features/analytics/setup.md +114 -0
- package/docs/features/analytics/tracking-events.md +224 -0
- package/docs/features/i18n/README.md +51 -0
- package/docs/features/i18n/best-practices.md +273 -0
- package/docs/features/i18n/configuration.md +84 -0
- package/docs/features/i18n/formatting.md +133 -0
- package/docs/features/i18n/locale-detection.md +122 -0
- package/docs/features/i18n/routing.md +99 -0
- package/docs/features/i18n/rtl-support.md +191 -0
- package/docs/features/i18n/translations.md +129 -0
- package/docs/features/internationalization.md +595 -0
- package/docs/features/performance/README.md +77 -0
- package/docs/features/performance/bundle-size.md +134 -0
- package/docs/features/performance/caching.md +131 -0
- package/docs/features/performance/code-splitting.md +121 -0
- package/docs/features/performance/image-optimization.md +110 -0
- package/docs/features/performance/lazy-loading.md +92 -0
- package/docs/features/performance/monitoring.md +148 -0
- package/docs/features/seo/README.md +51 -0
- package/docs/features/seo/best-practices.md +184 -0
- package/docs/features/seo/canonical-urls.md +182 -0
- package/docs/features/seo/meta-tags.md +126 -0
- package/docs/features/seo/open-graph.md +166 -0
- package/docs/features/seo/robots-txt.md +146 -0
- package/docs/features/seo/sitemaps.md +162 -0
- package/docs/features/seo/structured-data.md +166 -0
- package/docs/getting-started/installation.md +292 -0
- package/docs/getting-started/introduction.md +195 -0
- package/docs/getting-started/quick-start.md +460 -0
- package/docs/guides/analytics-setup.md +616 -0
- package/docs/i18n/CONFIGURATION.md +353 -0
- package/docs/i18n/EXAMPLES.md +402 -0
- package/docs/i18n/MIGRATION.md +260 -0
- package/docs/i18n/SEO.md +392 -0
- package/docs/i18n/STATIC-GENERATION-FIX.md +71 -0
- package/docs/migration/changelog.md +136 -0
- package/docs/migration/overview.md +233 -0
- package/docs/recipes/adding-animations.md +475 -0
- package/docs/recipes/forms-with-validation.md +393 -0
- package/package.json +152 -0
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
# CTASection
|
|
2
|
+
|
|
3
|
+
Full-width call-to-action section with dual-button layout. Battle-tested on courrielleur.com across 5+ pages for consistent conversion messaging.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { CTASection } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component (default export)
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<CTASection
|
|
17
|
+
heading="Ready to Get Started?"
|
|
18
|
+
description="Join thousands of satisfied customers"
|
|
19
|
+
primaryCTA={{
|
|
20
|
+
text: 'Start Free Trial',
|
|
21
|
+
href: '/signup'
|
|
22
|
+
}}
|
|
23
|
+
locale="en"
|
|
24
|
+
/>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Props
|
|
28
|
+
|
|
29
|
+
### Required Props
|
|
30
|
+
|
|
31
|
+
| Prop | Type | Description |
|
|
32
|
+
|------|------|-------------|
|
|
33
|
+
| `heading` | `string \| LocalizedString` | Main CTA heading |
|
|
34
|
+
| `primaryCTA` | `CTAConfig` | Primary call-to-action button |
|
|
35
|
+
| `locale` | `string` | Current locale |
|
|
36
|
+
|
|
37
|
+
### Optional Props
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default | Description |
|
|
40
|
+
|------|------|---------|-------------|
|
|
41
|
+
| `description` | `string \| LocalizedString` | - | Supporting description text |
|
|
42
|
+
| `secondaryCTA` | `CTAConfig` | - | Secondary call-to-action button |
|
|
43
|
+
| `variant` | `'centered' \| 'split' \| 'inline'` | `'centered'` | Layout variant |
|
|
44
|
+
| `buttonLayout` | `'horizontal' \| 'vertical'` | `'horizontal'` | Button arrangement |
|
|
45
|
+
| `backgroundColor` | `string` | `'bg-warm-gray'` | Background color class |
|
|
46
|
+
| `align` | `'left' \| 'center' \| 'right'` | `'center'` | Text alignment |
|
|
47
|
+
| `maxWidth` | `MaxWidth` | `'2xl'` | Maximum content width |
|
|
48
|
+
| `className` | `string` | - | Custom CSS classes |
|
|
49
|
+
|
|
50
|
+
### Type Definitions
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
interface CTAConfig {
|
|
54
|
+
text: string | LocalizedString;
|
|
55
|
+
href: string;
|
|
56
|
+
onClick?: () => void;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type LocalizedString = {
|
|
60
|
+
[locale: string]: string;
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Variants
|
|
65
|
+
|
|
66
|
+
### Centered (Default)
|
|
67
|
+
|
|
68
|
+
Traditional centered layout with buttons below text:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
<CTASection
|
|
72
|
+
heading="Transform Your Business Today"
|
|
73
|
+
description="Join 10,000+ companies using our platform"
|
|
74
|
+
primaryCTA={{
|
|
75
|
+
text: 'Start Free Trial',
|
|
76
|
+
href: '/signup'
|
|
77
|
+
}}
|
|
78
|
+
secondaryCTA={{
|
|
79
|
+
text: 'Schedule Demo',
|
|
80
|
+
href: '/demo'
|
|
81
|
+
}}
|
|
82
|
+
variant="centered"
|
|
83
|
+
locale="en"
|
|
84
|
+
/>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Best for:** End-of-page CTAs, conversion-focused sections
|
|
88
|
+
|
|
89
|
+
### Split
|
|
90
|
+
|
|
91
|
+
Content on left, buttons on right:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
<CTASection
|
|
95
|
+
heading="Ready to Scale?"
|
|
96
|
+
description="Take your business to the next level"
|
|
97
|
+
primaryCTA={{
|
|
98
|
+
text: 'Get Started',
|
|
99
|
+
href: '/signup'
|
|
100
|
+
}}
|
|
101
|
+
variant="split"
|
|
102
|
+
locale="en"
|
|
103
|
+
/>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Best for:** Mid-page CTAs, feature sections
|
|
107
|
+
|
|
108
|
+
### Inline
|
|
109
|
+
|
|
110
|
+
Horizontal layout with inline buttons:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
<CTASection
|
|
114
|
+
heading="Limited Time Offer"
|
|
115
|
+
description="Save 50% on annual plans"
|
|
116
|
+
primaryCTA={{
|
|
117
|
+
text: 'Claim Offer',
|
|
118
|
+
href: '/pricing'
|
|
119
|
+
}}
|
|
120
|
+
variant="inline"
|
|
121
|
+
locale="en"
|
|
122
|
+
/>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Best for:** Promotions, urgent CTAs, banners
|
|
126
|
+
|
|
127
|
+
## Examples
|
|
128
|
+
|
|
129
|
+
### Simple CTA
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
<CTASection
|
|
133
|
+
heading="Start Your Journey"
|
|
134
|
+
primaryCTA={{
|
|
135
|
+
text: 'Sign Up Free',
|
|
136
|
+
href: '/signup'
|
|
137
|
+
}}
|
|
138
|
+
locale="en"
|
|
139
|
+
/>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### With Description
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
<CTASection
|
|
146
|
+
heading="Experience the Difference"
|
|
147
|
+
description="No credit card required • Cancel anytime • 14-day free trial"
|
|
148
|
+
primaryCTA={{
|
|
149
|
+
text: 'Try Free for 14 Days',
|
|
150
|
+
href: '/signup'
|
|
151
|
+
}}
|
|
152
|
+
locale="en"
|
|
153
|
+
/>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Two Buttons
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
<CTASection
|
|
160
|
+
heading="Choose Your Path"
|
|
161
|
+
description="Get started with the plan that's right for you"
|
|
162
|
+
primaryCTA={{
|
|
163
|
+
text: 'Start Free Trial',
|
|
164
|
+
href: '/signup'
|
|
165
|
+
}}
|
|
166
|
+
secondaryCTA={{
|
|
167
|
+
text: 'Compare Plans',
|
|
168
|
+
href: '/pricing'
|
|
169
|
+
}}
|
|
170
|
+
locale="en"
|
|
171
|
+
/>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Vertical Button Layout
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
<CTASection
|
|
178
|
+
heading="Join Our Community"
|
|
179
|
+
description="Connect with professionals worldwide"
|
|
180
|
+
primaryCTA={{
|
|
181
|
+
text: 'Create Free Account',
|
|
182
|
+
href: '/signup'
|
|
183
|
+
}}
|
|
184
|
+
secondaryCTA={{
|
|
185
|
+
text: 'Learn More',
|
|
186
|
+
href: '/about'
|
|
187
|
+
}}
|
|
188
|
+
buttonLayout="vertical"
|
|
189
|
+
locale="en"
|
|
190
|
+
/>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Multi-Language
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
<CTASection
|
|
197
|
+
heading={{
|
|
198
|
+
en: 'Ready to Get Started?',
|
|
199
|
+
fr: 'Prêt à commencer?',
|
|
200
|
+
es: '¿Listo para comenzar?'
|
|
201
|
+
}}
|
|
202
|
+
description={{
|
|
203
|
+
en: 'Join thousands of satisfied customers',
|
|
204
|
+
fr: 'Rejoignez des milliers de clients satisfaits',
|
|
205
|
+
es: 'Únase a miles de clientes satisfechos'
|
|
206
|
+
}}
|
|
207
|
+
primaryCTA={{
|
|
208
|
+
text: {
|
|
209
|
+
en: 'Start Free Trial',
|
|
210
|
+
fr: 'Commencer l\'essai gratuit',
|
|
211
|
+
es: 'Comenzar prueba gratuita'
|
|
212
|
+
},
|
|
213
|
+
href: '/signup'
|
|
214
|
+
}}
|
|
215
|
+
secondaryCTA={{
|
|
216
|
+
text: {
|
|
217
|
+
en: 'View Pricing',
|
|
218
|
+
fr: 'Voir les tarifs',
|
|
219
|
+
es: 'Ver precios'
|
|
220
|
+
},
|
|
221
|
+
href: '/pricing'
|
|
222
|
+
}}
|
|
223
|
+
locale={locale}
|
|
224
|
+
/>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Custom Background
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
<CTASection
|
|
231
|
+
heading="Special Offer"
|
|
232
|
+
description="Limited time only"
|
|
233
|
+
primaryCTA={{
|
|
234
|
+
text: 'Claim Now',
|
|
235
|
+
href: '/offer'
|
|
236
|
+
}}
|
|
237
|
+
backgroundColor="bg-gradient-to-r from-orange-500 to-red-600"
|
|
238
|
+
locale="en"
|
|
239
|
+
/>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Left-Aligned
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
<CTASection
|
|
246
|
+
heading="Ready to Scale?"
|
|
247
|
+
description="Take your business to the next level"
|
|
248
|
+
primaryCTA={{
|
|
249
|
+
text: 'Get Started',
|
|
250
|
+
href: '/signup'
|
|
251
|
+
}}
|
|
252
|
+
align="left"
|
|
253
|
+
locale="en"
|
|
254
|
+
/>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### With Analytics
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
<CTASection
|
|
261
|
+
heading="Start Your Trial"
|
|
262
|
+
primaryCTA={{
|
|
263
|
+
text: 'Sign Up Free',
|
|
264
|
+
href: '/signup',
|
|
265
|
+
onClick: () => {
|
|
266
|
+
trackEvent('cta_section_click', {
|
|
267
|
+
location: 'pricing_page',
|
|
268
|
+
cta_text: 'Sign Up Free'
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}}
|
|
272
|
+
locale="en"
|
|
273
|
+
/>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Styling
|
|
277
|
+
|
|
278
|
+
### Custom Colors
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
<CTASection
|
|
282
|
+
heading="Limited Offer"
|
|
283
|
+
primaryCTA={{ text: 'Claim Now', href: '/offer' }}
|
|
284
|
+
className="bg-purple-900 text-white"
|
|
285
|
+
locale="en"
|
|
286
|
+
/>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Custom Spacing
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
<CTASection
|
|
293
|
+
heading="Join Us"
|
|
294
|
+
primaryCTA={{ text: 'Sign Up', href: '/signup' }}
|
|
295
|
+
className="py-32" // Extra padding
|
|
296
|
+
locale="en"
|
|
297
|
+
/>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Custom Button Styling
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
<CTASection
|
|
304
|
+
heading="Get Started"
|
|
305
|
+
primaryCTA={{ text: 'Start Now', href: '/signup' }}
|
|
306
|
+
className="[&_a]:bg-gradient-to-r [&_a]:from-blue-500 [&_a]:to-indigo-600"
|
|
307
|
+
locale="en"
|
|
308
|
+
/>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Common Patterns
|
|
312
|
+
|
|
313
|
+
### End of Homepage
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
<CTASection
|
|
317
|
+
heading="Ready to Transform Your Business?"
|
|
318
|
+
description="Join 10,000+ companies already using our platform"
|
|
319
|
+
primaryCTA={{
|
|
320
|
+
text: 'Start Free Trial',
|
|
321
|
+
href: '/signup'
|
|
322
|
+
}}
|
|
323
|
+
secondaryCTA={{
|
|
324
|
+
text: 'Schedule a Demo',
|
|
325
|
+
href: '/demo'
|
|
326
|
+
}}
|
|
327
|
+
backgroundColor="bg-gradient-to-br from-blue-50 to-indigo-100"
|
|
328
|
+
locale="en"
|
|
329
|
+
/>
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Pricing Page CTA
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
<CTASection
|
|
336
|
+
heading="Still Have Questions?"
|
|
337
|
+
description="Our team is here to help you choose the right plan"
|
|
338
|
+
primaryCTA={{
|
|
339
|
+
text: 'Talk to Sales',
|
|
340
|
+
href: '/contact'
|
|
341
|
+
}}
|
|
342
|
+
secondaryCTA={{
|
|
343
|
+
text: 'View FAQ',
|
|
344
|
+
href: '/faq'
|
|
345
|
+
}}
|
|
346
|
+
locale="en"
|
|
347
|
+
/>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Blog Post CTA
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
<CTASection
|
|
354
|
+
heading="Want More Insights?"
|
|
355
|
+
description="Subscribe to our newsletter for weekly tips"
|
|
356
|
+
primaryCTA={{
|
|
357
|
+
text: 'Subscribe Now',
|
|
358
|
+
href: '/newsletter'
|
|
359
|
+
}}
|
|
360
|
+
variant="inline"
|
|
361
|
+
backgroundColor="bg-gray-100"
|
|
362
|
+
locale="en"
|
|
363
|
+
/>
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Service Page CTA
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
<CTASection
|
|
370
|
+
heading="Let's Discuss Your Project"
|
|
371
|
+
description="Get a free consultation and project estimate"
|
|
372
|
+
primaryCTA={{
|
|
373
|
+
text: 'Request Quote',
|
|
374
|
+
href: '/quote'
|
|
375
|
+
}}
|
|
376
|
+
secondaryCTA={{
|
|
377
|
+
text: 'View Portfolio',
|
|
378
|
+
href: '/portfolio'
|
|
379
|
+
}}
|
|
380
|
+
variant="split"
|
|
381
|
+
locale="en"
|
|
382
|
+
/>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Promotion CTA
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
<CTASection
|
|
389
|
+
heading="Black Friday Sale - 50% Off!"
|
|
390
|
+
description="Limited time offer • Ends in 48 hours"
|
|
391
|
+
primaryCTA={{
|
|
392
|
+
text: 'Claim Discount',
|
|
393
|
+
href: '/pricing?promo=blackfriday'
|
|
394
|
+
}}
|
|
395
|
+
backgroundColor="bg-black text-white"
|
|
396
|
+
locale="en"
|
|
397
|
+
/>
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## Production Evidence
|
|
401
|
+
|
|
402
|
+
### Courrielleur.com Results
|
|
403
|
+
|
|
404
|
+
**Usage:** 5+ pages (homepage, pricing, features, about, contact)
|
|
405
|
+
|
|
406
|
+
**Patterns:**
|
|
407
|
+
- Homepage: Trial signup + demo
|
|
408
|
+
- Pricing: Contact sales + FAQ
|
|
409
|
+
- Features: Trial signup + learn more
|
|
410
|
+
- About: Contact + careers
|
|
411
|
+
- Blog: Newsletter + trial
|
|
412
|
+
|
|
413
|
+
**Benefits:**
|
|
414
|
+
- Consistent messaging across site
|
|
415
|
+
- Easy to A/B test CTA copy
|
|
416
|
+
- Single source of truth for conversion points
|
|
417
|
+
|
|
418
|
+
## Analytics Integration
|
|
419
|
+
|
|
420
|
+
### Track CTA Clicks
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
<CTASection
|
|
424
|
+
heading="Get Started"
|
|
425
|
+
primaryCTA={{
|
|
426
|
+
text: 'Sign Up',
|
|
427
|
+
href: '/signup',
|
|
428
|
+
onClick: () => {
|
|
429
|
+
trackEvent('primary_cta_click', {
|
|
430
|
+
section: 'cta_section',
|
|
431
|
+
page: window.location.pathname,
|
|
432
|
+
cta_text: 'Sign Up'
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
}}
|
|
436
|
+
secondaryCTA={{
|
|
437
|
+
text: 'Learn More',
|
|
438
|
+
href: '/about',
|
|
439
|
+
onClick: () => {
|
|
440
|
+
trackEvent('secondary_cta_click', {
|
|
441
|
+
section: 'cta_section',
|
|
442
|
+
page: window.location.pathname,
|
|
443
|
+
cta_text: 'Learn More'
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}}
|
|
447
|
+
locale="en"
|
|
448
|
+
/>
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Track Impressions
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
'use client';
|
|
455
|
+
|
|
456
|
+
import { CTASection } from '@zoyth/simple-site-framework';
|
|
457
|
+
import { useEffect } from 'react';
|
|
458
|
+
|
|
459
|
+
export function TrackedCTASection(props) {
|
|
460
|
+
useEffect(() => {
|
|
461
|
+
trackEvent('cta_section_view', {
|
|
462
|
+
page: window.location.pathname,
|
|
463
|
+
heading: props.heading
|
|
464
|
+
});
|
|
465
|
+
}, []);
|
|
466
|
+
|
|
467
|
+
return <CTASection {...props} />;
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
## Accessibility
|
|
472
|
+
|
|
473
|
+
CTASection includes:
|
|
474
|
+
|
|
475
|
+
- ✅ Semantic HTML (`<section>`, `<a>` links)
|
|
476
|
+
- ✅ Proper heading hierarchy
|
|
477
|
+
- ✅ Keyboard accessible links
|
|
478
|
+
- ✅ Focus visible states
|
|
479
|
+
- ✅ Sufficient color contrast (when using default theme)
|
|
480
|
+
- ✅ Screen reader friendly
|
|
481
|
+
- ✅ No onClick-only buttons (uses real links)
|
|
482
|
+
|
|
483
|
+
## SEO
|
|
484
|
+
|
|
485
|
+
- Uses semantic `<section>` tag
|
|
486
|
+
- Proper heading hierarchy
|
|
487
|
+
- Real `<a>` links (not JavaScript navigation)
|
|
488
|
+
- Descriptive link text
|
|
489
|
+
|
|
490
|
+
## Best Practices
|
|
491
|
+
|
|
492
|
+
### ✅ Do
|
|
493
|
+
|
|
494
|
+
- Use action-oriented text ("Start Free Trial" not "Submit")
|
|
495
|
+
- Keep heading concise (under 60 characters)
|
|
496
|
+
- Make primary CTA stand out visually
|
|
497
|
+
- Place at natural break points (end of page, after features)
|
|
498
|
+
- Use consistent CTA messaging site-wide
|
|
499
|
+
- Track clicks to measure effectiveness
|
|
500
|
+
|
|
501
|
+
### ❌ Don't
|
|
502
|
+
|
|
503
|
+
- Use vague text ("Click Here", "Learn More" alone)
|
|
504
|
+
- Have competing CTAs of equal prominence
|
|
505
|
+
- Overuse throughout the page (1-2 max per page)
|
|
506
|
+
- Make both buttons look identical
|
|
507
|
+
- Forget to test different copy variations
|
|
508
|
+
- Hide secondary CTA if it provides value
|
|
509
|
+
|
|
510
|
+
## A/B Testing
|
|
511
|
+
|
|
512
|
+
### Test CTA Copy
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
import { getABTestVariant } from '@zoyth/simple-site-framework/client';
|
|
516
|
+
|
|
517
|
+
const variant = getABTestVariant({
|
|
518
|
+
testId: 'cta_copy_test',
|
|
519
|
+
variants: { A: { weight: 50 }, B: { weight: 50 } }
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
const ctaText = variant === 'A'
|
|
523
|
+
? 'Start Free Trial'
|
|
524
|
+
: 'Try Free for 14 Days';
|
|
525
|
+
|
|
526
|
+
<CTASection
|
|
527
|
+
heading="Ready to Get Started?"
|
|
528
|
+
primaryCTA={{
|
|
529
|
+
text: ctaText,
|
|
530
|
+
href: '/signup',
|
|
531
|
+
onClick: () => {
|
|
532
|
+
trackABTestEvent('cta_copy_test', variant, 'click');
|
|
533
|
+
}
|
|
534
|
+
}}
|
|
535
|
+
locale="en"
|
|
536
|
+
/>
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Test Button Layout
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
const variant = getABTestVariant({
|
|
543
|
+
testId: 'button_layout_test',
|
|
544
|
+
variants: { A: { weight: 50 }, B: { weight: 50 } }
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
<CTASection
|
|
548
|
+
heading="Get Started"
|
|
549
|
+
primaryCTA={{ text: 'Sign Up', href: '/signup' }}
|
|
550
|
+
secondaryCTA={{ text: 'Learn More', href: '/about' }}
|
|
551
|
+
buttonLayout={variant === 'A' ? 'horizontal' : 'vertical'}
|
|
552
|
+
locale="en"
|
|
553
|
+
/>
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
## Troubleshooting
|
|
557
|
+
|
|
558
|
+
### Buttons not clickable
|
|
559
|
+
|
|
560
|
+
**Check:**
|
|
561
|
+
1. `href` is provided in CTA config
|
|
562
|
+
2. No z-index conflicts
|
|
563
|
+
3. No overlay blocking clicks
|
|
564
|
+
4. CSS not setting `pointer-events: none`
|
|
565
|
+
|
|
566
|
+
### Wrong text displaying in multi-language
|
|
567
|
+
|
|
568
|
+
**Check:**
|
|
569
|
+
1. `locale` prop is provided
|
|
570
|
+
2. LocalizedString has entry for that locale
|
|
571
|
+
3. Fallback locale exists
|
|
572
|
+
|
|
573
|
+
### Buttons not styled correctly
|
|
574
|
+
|
|
575
|
+
**Check:**
|
|
576
|
+
1. Tailwind config includes framework in `content` array
|
|
577
|
+
2. Theme colors are defined
|
|
578
|
+
3. No CSS overriding default styles
|
|
579
|
+
|
|
580
|
+
### Analytics not firing
|
|
581
|
+
|
|
582
|
+
**Check:**
|
|
583
|
+
1. `onClick` handler is provided
|
|
584
|
+
2. Handler is actually being called (add console.log)
|
|
585
|
+
3. Analytics library is loaded
|
|
586
|
+
4. dataLayer exists
|
|
587
|
+
|
|
588
|
+
## Related Components
|
|
589
|
+
|
|
590
|
+
- **[HeroSection](./HeroSection.md)** - Page header with CTA
|
|
591
|
+
- **[MobileCTA](../conversion/MobileCTA.md)** - Mobile-only sticky CTA
|
|
592
|
+
- **[Button](../ui/Button.md)** - Base button component
|
|
593
|
+
|
|
594
|
+
## API Reference
|
|
595
|
+
|
|
596
|
+
Full TypeScript definitions: **[API Reference](../../api/components.md#ctasection)**
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# CaseStudySection
|
|
2
|
+
|
|
3
|
+
Case study display section.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { CaseStudySection } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<CaseStudySection
|
|
17
|
+
title="How Acme Corp Increased Revenue by 300%"
|
|
18
|
+
client="Acme Corporation"
|
|
19
|
+
industry="Technology"
|
|
20
|
+
challenge="Low conversion rates"
|
|
21
|
+
solution="Implemented new marketing strategy"
|
|
22
|
+
results={[
|
|
23
|
+
'300% revenue increase',
|
|
24
|
+
'50% more leads',
|
|
25
|
+
'10x ROI',
|
|
26
|
+
]}
|
|
27
|
+
/>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Props
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Required | Description |
|
|
33
|
+
|------|------|----------|-------------|
|
|
34
|
+
| `title` | `string \| LocalizedString` | Yes | Case study title |
|
|
35
|
+
| `client` | `string` | Yes | Client name |
|
|
36
|
+
| `industry` | `string` | No | Industry |
|
|
37
|
+
| `challenge` | `string \| LocalizedString` | No | Challenge description |
|
|
38
|
+
| `solution` | `string \| LocalizedString` | No | Solution description |
|
|
39
|
+
| `results` | `string[]` | No | Results/outcomes |
|
|
40
|
+
| `testimonial` | `Testimonial` | No | Client testimonial |
|
|
41
|
+
| `className` | `string` | No | Custom classes |
|
|
42
|
+
| `locale` | `string` | No | Current locale |
|
|
43
|
+
|
|
44
|
+
## See Also
|
|
45
|
+
|
|
46
|
+
- [TestimonialSection](./TestimonialSection.md)
|
|
47
|
+
- [AboutSection](./AboutSection.md)
|