@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,47 @@
|
|
|
1
|
+
# TableOfContents
|
|
2
|
+
|
|
3
|
+
Auto-generated table of contents from page headings.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { TableOfContents } from '@zoyth/simple-site-framework/client';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Client Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<TableOfContents
|
|
17
|
+
containerSelector="article"
|
|
18
|
+
includeLevels={[2, 3]}
|
|
19
|
+
/>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Props
|
|
23
|
+
|
|
24
|
+
| Prop | Type | Required | Description |
|
|
25
|
+
|------|------|----------|-------------|
|
|
26
|
+
| `containerSelector` | `string` | No | Content container selector (default: 'article') |
|
|
27
|
+
| `includeLevels` | `number[]` | No | Heading levels to include (default: [2, 3]) |
|
|
28
|
+
| `title` | `string \| LocalizedString` | No | TOC title |
|
|
29
|
+
| `className` | `string` | No | Custom classes |
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// Basic TOC
|
|
35
|
+
<TableOfContents />
|
|
36
|
+
|
|
37
|
+
// Include h2, h3, h4
|
|
38
|
+
<TableOfContents includeLevels={[2, 3, 4]} />
|
|
39
|
+
|
|
40
|
+
// Custom title
|
|
41
|
+
<TableOfContents title="On This Page" />
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## See Also
|
|
45
|
+
|
|
46
|
+
- [PolicyLayout](./PolicyLayout.md)
|
|
47
|
+
- [CodeBlock](./CodeBlock.md)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# TestimonialCarousel
|
|
2
|
+
|
|
3
|
+
Carousel/slider for testimonials.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { TestimonialCarousel } from '@zoyth/simple-site-framework/client';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Client Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<TestimonialCarousel
|
|
17
|
+
testimonials={[
|
|
18
|
+
{
|
|
19
|
+
quote: "Amazing product!",
|
|
20
|
+
author: "Jane Doe",
|
|
21
|
+
role: "CEO",
|
|
22
|
+
company: "Acme Inc",
|
|
23
|
+
},
|
|
24
|
+
]}
|
|
25
|
+
/>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Props
|
|
29
|
+
|
|
30
|
+
| Prop | Type | Required | Description |
|
|
31
|
+
|------|------|----------|-------------|
|
|
32
|
+
| `testimonials` | `Testimonial[]` | Yes | Testimonial items |
|
|
33
|
+
| `autoplay` | `boolean` | No | Auto-advance slides |
|
|
34
|
+
| `interval` | `number` | No | Autoplay interval (ms) |
|
|
35
|
+
| `showControls` | `boolean` | No | Show prev/next buttons |
|
|
36
|
+
| `showDots` | `boolean` | No | Show navigation dots |
|
|
37
|
+
| `className` | `string` | No | Custom classes |
|
|
38
|
+
| `locale` | `string` | No | Current locale |
|
|
39
|
+
|
|
40
|
+
## See Also
|
|
41
|
+
|
|
42
|
+
- [TestimonialSection](./sections/TestimonialSection.md)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Timeline
|
|
2
|
+
|
|
3
|
+
Timeline component for chronological events.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Timeline } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<Timeline
|
|
17
|
+
events={[
|
|
18
|
+
{
|
|
19
|
+
year: '2024',
|
|
20
|
+
title: 'Company Milestone',
|
|
21
|
+
description: 'Reached 10,000 customers',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
year: '2023',
|
|
25
|
+
title: 'Series A Funding',
|
|
26
|
+
description: 'Raised $10M in funding',
|
|
27
|
+
},
|
|
28
|
+
]}
|
|
29
|
+
/>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Props
|
|
33
|
+
|
|
34
|
+
| Prop | Type | Required | Description |
|
|
35
|
+
|------|------|----------|-------------|
|
|
36
|
+
| `events` | `TimelineEvent[]` | Yes | Timeline events |
|
|
37
|
+
| `variant` | `'vertical' \| 'horizontal'` | No | Layout variant |
|
|
38
|
+
| `className` | `string` | No | Custom classes |
|
|
39
|
+
| `locale` | `string` | No | Current locale |
|
|
40
|
+
|
|
41
|
+
### TimelineEvent
|
|
42
|
+
|
|
43
|
+
| Prop | Type | Required | Description |
|
|
44
|
+
|------|------|----------|-------------|
|
|
45
|
+
| `year` | `string` | Yes | Event year/date |
|
|
46
|
+
| `title` | `string \| LocalizedString` | Yes | Event title |
|
|
47
|
+
| `description` | `string \| LocalizedString` | No | Event description |
|
|
48
|
+
|
|
49
|
+
## See Also
|
|
50
|
+
|
|
51
|
+
- [AboutSection](./sections/AboutSection.md)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Toast
|
|
2
|
+
|
|
3
|
+
Toast notification component.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Toast } from '@zoyth/simple-site-framework/client';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Client Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<Toast
|
|
17
|
+
message="Successfully saved!"
|
|
18
|
+
type="success"
|
|
19
|
+
onClose={() => setShowToast(false)}
|
|
20
|
+
/>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Props
|
|
24
|
+
|
|
25
|
+
| Prop | Type | Required | Description |
|
|
26
|
+
|------|------|----------|-------------|
|
|
27
|
+
| `message` | `string \| LocalizedString` | Yes | Notification message |
|
|
28
|
+
| `type` | `'success' \| 'error' \| 'info' \| 'warning'` | Yes | Toast type |
|
|
29
|
+
| `duration` | `number` | No | Auto-close duration (ms) |
|
|
30
|
+
| `onClose` | `function` | No | Close handler |
|
|
31
|
+
| `className` | `string` | No | Custom classes |
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// Success toast
|
|
37
|
+
<Toast
|
|
38
|
+
message="Settings saved successfully"
|
|
39
|
+
type="success"
|
|
40
|
+
duration={3000}
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
// Error toast
|
|
44
|
+
<Toast
|
|
45
|
+
message="Failed to save. Please try again."
|
|
46
|
+
type="error"
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
// Info toast (no auto-close)
|
|
50
|
+
<Toast
|
|
51
|
+
message="New features available"
|
|
52
|
+
type="info"
|
|
53
|
+
onClose={() => setShow(false)}
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## See Also
|
|
58
|
+
|
|
59
|
+
- [Modal](./ui/Modal.md)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# TrackedLink
|
|
2
|
+
|
|
3
|
+
Link component with automatic click tracking.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { TrackedLink } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<TrackedLink
|
|
17
|
+
href="/pricing"
|
|
18
|
+
eventName="pricing_link_click"
|
|
19
|
+
eventData={{ location: 'footer' }}
|
|
20
|
+
>
|
|
21
|
+
View Pricing
|
|
22
|
+
</TrackedLink>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Required | Description |
|
|
28
|
+
|------|------|----------|-------------|
|
|
29
|
+
| `href` | `string` | Yes | Link URL |
|
|
30
|
+
| `eventName` | `string` | Yes | Event name for tracking |
|
|
31
|
+
| `eventData` | `object` | No | Additional event data |
|
|
32
|
+
| `children` | `ReactNode` | Yes | Link content |
|
|
33
|
+
| `className` | `string` | No | Custom classes |
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// Footer link
|
|
39
|
+
<TrackedLink
|
|
40
|
+
href="/contact"
|
|
41
|
+
eventName="footer_contact_click"
|
|
42
|
+
>
|
|
43
|
+
Contact Us
|
|
44
|
+
</TrackedLink>
|
|
45
|
+
|
|
46
|
+
// With metadata
|
|
47
|
+
<TrackedLink
|
|
48
|
+
href="/blog/article-1"
|
|
49
|
+
eventName="blog_article_click"
|
|
50
|
+
eventData={{
|
|
51
|
+
article_id: '1',
|
|
52
|
+
category: 'tutorials'
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
Read Article
|
|
56
|
+
</TrackedLink>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## See Also
|
|
60
|
+
|
|
61
|
+
- [AnalyticsTracker](./AnalyticsTracker.md)
|
|
62
|
+
- [Button](./ui/Button.md)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# TrustBadges
|
|
2
|
+
|
|
3
|
+
Trust and security badges component.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { TrustBadges } from '@zoyth/simple-site-framework';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Server Component
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
<TrustBadges
|
|
17
|
+
badges={[
|
|
18
|
+
{ name: 'SSL Secure', icon: 'shield' },
|
|
19
|
+
{ name: 'Money Back Guarantee', icon: 'check' },
|
|
20
|
+
{ name: '24/7 Support', icon: 'clock' },
|
|
21
|
+
]}
|
|
22
|
+
/>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Required | Description |
|
|
28
|
+
|------|------|----------|-------------|
|
|
29
|
+
| `badges` | `Badge[]` | Yes | Trust badges |
|
|
30
|
+
| `variant` | `'icons' \| 'logos'` | No | Display variant |
|
|
31
|
+
| `className` | `string` | No | Custom classes |
|
|
32
|
+
|
|
33
|
+
### Badge
|
|
34
|
+
|
|
35
|
+
| Prop | Type | Required | Description |
|
|
36
|
+
|------|------|----------|-------------|
|
|
37
|
+
| `name` | `string \| LocalizedString` | Yes | Badge name |
|
|
38
|
+
| `icon` | `string` | No | Icon name |
|
|
39
|
+
| `logo` | `string` | No | Logo image URL |
|
|
40
|
+
|
|
41
|
+
## See Also
|
|
42
|
+
|
|
43
|
+
- [Footer](./layout/Footer.md)
|
|
44
|
+
- [TestimonialSection](./sections/TestimonialSection.md)
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# MobileCTA
|
|
2
|
+
|
|
3
|
+
A sticky mobile-only CTA button that appears after scroll threshold. Battle-tested on courrielleur.com to improve mobile conversion rates.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { MobileCTA } from '@zoyth/simple-site-framework/client';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Type:** Client Component (`/client` export)
|
|
12
|
+
**Why Client:** Uses `window`, `scrollY`, and React hooks
|
|
13
|
+
|
|
14
|
+
## Basic Usage
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
<MobileCTA
|
|
18
|
+
text="Start Free Trial"
|
|
19
|
+
href="/signup"
|
|
20
|
+
locale="en"
|
|
21
|
+
/>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Props
|
|
25
|
+
|
|
26
|
+
### Required Props
|
|
27
|
+
|
|
28
|
+
| Prop | Type | Description |
|
|
29
|
+
|------|------|-------------|
|
|
30
|
+
| `text` | `string \| LocalizedString` | CTA button text |
|
|
31
|
+
| `href` | `string` | Destination URL |
|
|
32
|
+
| `locale` | `string` | Current locale (for LocalizedString) |
|
|
33
|
+
|
|
34
|
+
### Optional Props
|
|
35
|
+
|
|
36
|
+
| Prop | Type | Default | Description |
|
|
37
|
+
|------|------|---------|-------------|
|
|
38
|
+
| `threshold` | `number` | `300` | Scroll distance (px) before showing |
|
|
39
|
+
| `hideAbove` | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | `'lg'` | Breakpoint to hide on larger screens |
|
|
40
|
+
| `onClick` | `() => void` | - | Click handler (for analytics) |
|
|
41
|
+
| `className` | `string` | - | Custom CSS classes |
|
|
42
|
+
| `zIndex` | `number` | `50` | Z-index value |
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
### Simple Mobile CTA
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
<MobileCTA
|
|
50
|
+
text="Get Started"
|
|
51
|
+
href="/signup"
|
|
52
|
+
locale="en"
|
|
53
|
+
/>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Multi-Language
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
<MobileCTA
|
|
60
|
+
text={{
|
|
61
|
+
en: 'Start Free Trial - No Card Required',
|
|
62
|
+
fr: 'Essai gratuit - Aucune carte requise'
|
|
63
|
+
}}
|
|
64
|
+
href="/signup"
|
|
65
|
+
locale={locale}
|
|
66
|
+
/>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Custom Scroll Threshold
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
<MobileCTA
|
|
73
|
+
text="Contact Us"
|
|
74
|
+
href="/contact"
|
|
75
|
+
threshold={500} // Show after 500px scroll
|
|
76
|
+
locale="en"
|
|
77
|
+
/>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### With Analytics Tracking
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
<MobileCTA
|
|
84
|
+
text="Start Free Trial"
|
|
85
|
+
href="/signup"
|
|
86
|
+
locale="en"
|
|
87
|
+
onClick={() => {
|
|
88
|
+
trackEvent('mobile_cta_click', {
|
|
89
|
+
location: 'homepage',
|
|
90
|
+
scrollDepth: window.scrollY
|
|
91
|
+
});
|
|
92
|
+
}}
|
|
93
|
+
/>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Hide on Tablet and Up
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
<MobileCTA
|
|
100
|
+
text="Get Started"
|
|
101
|
+
href="/signup"
|
|
102
|
+
hideAbove="md" // Hide on md breakpoint and above
|
|
103
|
+
locale="en"
|
|
104
|
+
/>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Custom Z-Index
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
<MobileCTA
|
|
111
|
+
text="Sign Up"
|
|
112
|
+
href="/signup"
|
|
113
|
+
zIndex={100} // Ensure it's above modals/overlays
|
|
114
|
+
locale="en"
|
|
115
|
+
/>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Behavior
|
|
119
|
+
|
|
120
|
+
### Scroll Triggering
|
|
121
|
+
|
|
122
|
+
- **Hidden by default** - Doesn't appear immediately on page load
|
|
123
|
+
- **Appears on scroll** - Shows after scrolling past threshold (default 300px)
|
|
124
|
+
- **Smooth animation** - Slides up from bottom with transition
|
|
125
|
+
- **Stays visible** - Remains visible while scrolling further
|
|
126
|
+
|
|
127
|
+
### Responsive Display
|
|
128
|
+
|
|
129
|
+
- **Mobile only** - Hidden on desktop/tablet by default
|
|
130
|
+
- **Configurable breakpoint** - Use `hideAbove` to control when it hides
|
|
131
|
+
- **No layout shift** - Position fixed, doesn't affect page flow
|
|
132
|
+
|
|
133
|
+
### Accessibility
|
|
134
|
+
|
|
135
|
+
- **Semantic link** - Uses `<a>` tag, not button
|
|
136
|
+
- **Keyboard accessible** - Can be focused and activated with Enter
|
|
137
|
+
- **Screen reader friendly** - Announces as navigation link
|
|
138
|
+
- **44px min tap target** - Meets touch target size guidelines
|
|
139
|
+
|
|
140
|
+
## Performance
|
|
141
|
+
|
|
142
|
+
- **Passive scroll listener** - Doesn't block scrolling performance
|
|
143
|
+
- **No throttle/debounce needed** - Browser optimizes passive listeners
|
|
144
|
+
- **Minimal JavaScript** - ~1KB gzipped
|
|
145
|
+
- **CSS transitions** - Hardware-accelerated animations
|
|
146
|
+
|
|
147
|
+
## Styling
|
|
148
|
+
|
|
149
|
+
### Custom Colors
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
<MobileCTA
|
|
153
|
+
text="Get Started"
|
|
154
|
+
href="/signup"
|
|
155
|
+
className="bg-purple-600 hover:bg-purple-700"
|
|
156
|
+
locale="en"
|
|
157
|
+
/>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Custom Size
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
<MobileCTA
|
|
164
|
+
text="Sign Up"
|
|
165
|
+
href="/signup"
|
|
166
|
+
className="text-lg px-12 py-6"
|
|
167
|
+
locale="en"
|
|
168
|
+
/>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Custom Shadow
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
<MobileCTA
|
|
175
|
+
text="Try Now"
|
|
176
|
+
href="/trial"
|
|
177
|
+
className="shadow-2xl"
|
|
178
|
+
locale="en"
|
|
179
|
+
/>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Common Patterns
|
|
183
|
+
|
|
184
|
+
### Site-Wide Mobile CTA
|
|
185
|
+
|
|
186
|
+
Add to root layout for consistent mobile conversion:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
// src/app/layout.tsx
|
|
190
|
+
import { MobileCTA } from '@zoyth/simple-site-framework/client';
|
|
191
|
+
|
|
192
|
+
export default function RootLayout({ children }) {
|
|
193
|
+
return (
|
|
194
|
+
<html>
|
|
195
|
+
<body>
|
|
196
|
+
{children}
|
|
197
|
+
<MobileCTA
|
|
198
|
+
text={{ en: 'Start Free Trial', fr: 'Essai gratuit' }}
|
|
199
|
+
href="/signup"
|
|
200
|
+
locale="en"
|
|
201
|
+
/>
|
|
202
|
+
</body>
|
|
203
|
+
</html>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Page-Specific CTA
|
|
209
|
+
|
|
210
|
+
Different CTA per page:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
// src/app/pricing/page.tsx
|
|
214
|
+
<>
|
|
215
|
+
<PricingSection {...props} />
|
|
216
|
+
<MobileCTA
|
|
217
|
+
text="Start 14-Day Trial"
|
|
218
|
+
href="/signup?plan=pro"
|
|
219
|
+
locale="en"
|
|
220
|
+
/>
|
|
221
|
+
</>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### With Campaign Tracking
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
<MobileCTA
|
|
228
|
+
text="Special Offer"
|
|
229
|
+
href="/signup?ref=mobile_cta&campaign=summer2024"
|
|
230
|
+
onClick={() => {
|
|
231
|
+
trackCampaign('summer2024', 'mobile_cta_click');
|
|
232
|
+
}}
|
|
233
|
+
locale="en"
|
|
234
|
+
/>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Analytics Integration
|
|
238
|
+
|
|
239
|
+
### Track Visibility
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
'use client';
|
|
243
|
+
|
|
244
|
+
import { MobileCTA } from '@zoyth/simple-site-framework/client';
|
|
245
|
+
import { useEffect, useState } from 'react';
|
|
246
|
+
|
|
247
|
+
export default function PageWithCTA() {
|
|
248
|
+
const [ctaShown, setCtaShown] = useState(false);
|
|
249
|
+
|
|
250
|
+
useEffect(() => {
|
|
251
|
+
const handleScroll = () => {
|
|
252
|
+
if (window.scrollY > 300 && !ctaShown) {
|
|
253
|
+
setCtaShown(true);
|
|
254
|
+
trackEvent('mobile_cta_shown');
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
window.addEventListener('scroll', handleScroll);
|
|
259
|
+
return () => window.removeEventListener('scroll', handleScroll);
|
|
260
|
+
}, [ctaShown]);
|
|
261
|
+
|
|
262
|
+
return <MobileCTA text="Sign Up" href="/signup" locale="en" />;
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Track Clicks
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
<MobileCTA
|
|
270
|
+
text="Get Started"
|
|
271
|
+
href="/signup"
|
|
272
|
+
onClick={() => {
|
|
273
|
+
trackEvent('mobile_cta_click', {
|
|
274
|
+
page: window.location.pathname,
|
|
275
|
+
scrollDepth: window.scrollY,
|
|
276
|
+
timestamp: Date.now()
|
|
277
|
+
});
|
|
278
|
+
}}
|
|
279
|
+
locale="en"
|
|
280
|
+
/>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Best Practices
|
|
284
|
+
|
|
285
|
+
### ✅ Do
|
|
286
|
+
|
|
287
|
+
- Use action-oriented text ("Start Free Trial", "Get Quote")
|
|
288
|
+
- Keep text short (under 30 characters)
|
|
289
|
+
- Use consistent CTA across site
|
|
290
|
+
- Track clicks to measure effectiveness
|
|
291
|
+
- Test different scroll thresholds
|
|
292
|
+
|
|
293
|
+
### ❌ Don't
|
|
294
|
+
|
|
295
|
+
- Use vague text ("Click Here", "Learn More")
|
|
296
|
+
- Make text too long (wraps awkwardly)
|
|
297
|
+
- Show on desktop (defeats purpose)
|
|
298
|
+
- Set threshold too low (annoying)
|
|
299
|
+
- Forget to add analytics
|
|
300
|
+
|
|
301
|
+
## Troubleshooting
|
|
302
|
+
|
|
303
|
+
### CTA not appearing on mobile
|
|
304
|
+
|
|
305
|
+
**Check:**
|
|
306
|
+
1. Scrolled past threshold (`threshold` prop)
|
|
307
|
+
2. Screen width is below `hideAbove` breakpoint
|
|
308
|
+
3. CSS not overriding `position: fixed`
|
|
309
|
+
4. Z-index conflicts
|
|
310
|
+
|
|
311
|
+
### CTA showing on desktop
|
|
312
|
+
|
|
313
|
+
**Check:**
|
|
314
|
+
1. `hideAbove` prop is set correctly (default is `'lg'`)
|
|
315
|
+
2. Custom CSS not overriding responsive classes
|
|
316
|
+
3. Viewport width is actually above breakpoint
|
|
317
|
+
|
|
318
|
+
### Scroll performance issues
|
|
319
|
+
|
|
320
|
+
**Check:**
|
|
321
|
+
1. Not adding additional scroll listeners
|
|
322
|
+
2. Not using heavy onClick handlers
|
|
323
|
+
3. Browser supports passive event listeners
|
|
324
|
+
|
|
325
|
+
### Wrong language displaying
|
|
326
|
+
|
|
327
|
+
**Check:**
|
|
328
|
+
1. `locale` prop matches current route locale
|
|
329
|
+
2. LocalizedString has entry for current locale
|
|
330
|
+
3. Fallback locale exists in LocalizedString
|
|
331
|
+
|
|
332
|
+
## Production Evidence
|
|
333
|
+
|
|
334
|
+
### Courrielleur.com Results
|
|
335
|
+
|
|
336
|
+
- **Implementation:** Site-wide in root layout
|
|
337
|
+
- **Performance:** No measurable scroll performance impact
|
|
338
|
+
- **Conversions:** Positive improvement in mobile funnel
|
|
339
|
+
- **User Feedback:** No complaints about annoyance
|
|
340
|
+
|
|
341
|
+
### Recommended Settings
|
|
342
|
+
|
|
343
|
+
Based on production usage:
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
<MobileCTA
|
|
347
|
+
text="Start Free Trial"
|
|
348
|
+
href="/signup"
|
|
349
|
+
threshold={300} // Sweet spot for engagement
|
|
350
|
+
hideAbove="lg" // Standard desktop breakpoint
|
|
351
|
+
locale={locale}
|
|
352
|
+
/>
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## Related Components
|
|
356
|
+
|
|
357
|
+
- **[CTASection](../sections/CTASection.md)** - Desktop-optimized CTA section
|
|
358
|
+
- **[Button](../ui/Button.md)** - Base button component
|
|
359
|
+
- **[AnalyticsTracker](../utilities/AnalyticsTracker.md)** - Full analytics setup
|
|
360
|
+
|
|
361
|
+
## API Reference
|
|
362
|
+
|
|
363
|
+
Full TypeScript definitions: **[API Reference](../../api/components.md#mobilecta)**
|