@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,595 @@
1
+ # Internationalization (i18n)
2
+
3
+ Simple Site Framework provides flexible multi-language support that works for single-language sites, bilingual sites, or sites with 20+ languages.
4
+
5
+ ## Overview
6
+
7
+ The i18n system includes:
8
+
9
+ - **Flexible routing** - Single language (no overhead), bilingual, or multi-language
10
+ - **Automatic detection** - Browser language and cookie persistence
11
+ - **Type-safe content** - LocalizedString type with full TypeScript support
12
+ - **SEO optimized** - hreflang tags, canonical URLs, language alternates
13
+ - **Smart UI** - Language selector adapts (toggle for 2 languages, dropdown for 3+)
14
+
15
+ ## Quick Start
16
+
17
+ ### 1. Single Language Site (No i18n)
18
+
19
+ If you don't need multiple languages, just use strings:
20
+
21
+ ```typescript
22
+ <HeroSection
23
+ heading="Welcome to Our Site"
24
+ description="We help businesses grow"
25
+ />
26
+ ```
27
+
28
+ No configuration needed. No routing overhead.
29
+
30
+ ### 2. Bilingual Site
31
+
32
+ **Step 1:** Create i18n config
33
+
34
+ ```typescript
35
+ // src/config/i18n.ts
36
+ import type { I18nConfig } from '@zoyth/simple-site-framework';
37
+
38
+ export const i18nConfig: I18nConfig = {
39
+ locales: ['en', 'fr'],
40
+ defaultLocale: 'en',
41
+ localePrefix: 'as-needed', // /about for EN, /fr/about for FR
42
+ localeDetection: true,
43
+ };
44
+ ```
45
+
46
+ **Step 2:** Use LocalizedString
47
+
48
+ ```typescript
49
+ <HeroSection
50
+ heading={{
51
+ en: 'Welcome to Our Site',
52
+ fr: 'Bienvenue sur notre site'
53
+ }}
54
+ description={{
55
+ en: 'We help businesses grow',
56
+ fr: 'Nous aidons les entreprises à croître'
57
+ }}
58
+ locale={locale}
59
+ />
60
+ ```
61
+
62
+ **Step 3:** Language selector appears automatically
63
+
64
+ The framework renders a simple toggle between EN/FR.
65
+
66
+ ### 3. Multi-Language Site (3+ Languages)
67
+
68
+ ```typescript
69
+ // src/config/i18n.ts
70
+ export const i18nConfig: I18nConfig = {
71
+ locales: ['en', 'fr', 'es', 'de', 'ja'],
72
+ defaultLocale: 'en',
73
+ localePrefix: 'as-needed',
74
+ localeDetection: true,
75
+ localeNames: {
76
+ en: 'English',
77
+ fr: 'Français',
78
+ es: 'Español',
79
+ de: 'Deutsch',
80
+ ja: '日本語',
81
+ },
82
+ };
83
+ ```
84
+
85
+ The framework renders a dropdown selector with all 5 languages.
86
+
87
+ ## Configuration
88
+
89
+ ### I18nConfig Options
90
+
91
+ ```typescript
92
+ interface I18nConfig {
93
+ /** Supported locales */
94
+ locales: readonly string[];
95
+
96
+ /** Default/fallback locale */
97
+ defaultLocale: string;
98
+
99
+ /** URL prefix mode */
100
+ localePrefix?: 'always' | 'as-needed' | 'never';
101
+
102
+ /** Auto-detect browser language */
103
+ localeDetection?: boolean;
104
+
105
+ /** Full language names for UI */
106
+ localeNames?: Record<string, string>;
107
+
108
+ /** Short labels for compact UI */
109
+ localeLabels?: Record<string, string>;
110
+
111
+ /** RTL locales (Arabic, Hebrew) */
112
+ rtlLocales?: readonly string[];
113
+
114
+ /** Cookie configuration */
115
+ localeCookie?: {
116
+ name?: string;
117
+ maxAge?: number;
118
+ sameSite?: 'lax' | 'strict' | 'none';
119
+ };
120
+ }
121
+ ```
122
+
123
+ ### Locale Prefix Modes
124
+
125
+ #### 'as-needed' (Recommended)
126
+
127
+ Default locale has no prefix, others do:
128
+
129
+ ```
130
+ /about → English (default locale)
131
+ /fr/about → French
132
+ /es/about → Spanish
133
+ ```
134
+
135
+ **Benefits:**
136
+ - Clean URLs for default language
137
+ - SEO-friendly (default as canonical)
138
+ - Best user experience
139
+
140
+ #### 'always'
141
+
142
+ All locales have prefix:
143
+
144
+ ```
145
+ /en/about → English
146
+ /fr/about → French
147
+ /es/about → Spanish
148
+ ```
149
+
150
+ **Benefits:**
151
+ - Explicit language in every URL
152
+ - Equal treatment of all languages
153
+ - Easier to switch default locale later
154
+
155
+ #### 'never'
156
+
157
+ No prefixes, cookie/header detection only:
158
+
159
+ ```
160
+ /about → Shows based on user's language preference
161
+ ```
162
+
163
+ **Benefits:**
164
+ - Simplest URLs
165
+ - Good for markets with one dominant language
166
+
167
+ **Drawbacks:**
168
+ - Harder to share specific language links
169
+ - Requires JavaScript for language switching
170
+
171
+ ## LocalizedString Type
172
+
173
+ The core i18n type:
174
+
175
+ ```typescript
176
+ type LocalizedString = {
177
+ [locale: string]: string;
178
+ };
179
+
180
+ // Example
181
+ const heading: LocalizedString = {
182
+ en: 'About Us',
183
+ fr: 'À propos de nous',
184
+ es: 'Sobre nosotros'
185
+ };
186
+ ```
187
+
188
+ ### Type-Safe LocalizedStrings
189
+
190
+ Enforce required locales:
191
+
192
+ ```typescript
193
+ type RequiredLocales<T> = {
194
+ [K in 'en' | 'fr']: T;
195
+ };
196
+
197
+ const heading: RequiredLocales<string> = {
198
+ en: 'Welcome',
199
+ fr: 'Bienvenue',
200
+ // TypeScript error if missing either
201
+ };
202
+ ```
203
+
204
+ ### Using in Components
205
+
206
+ All framework components accept LocalizedString:
207
+
208
+ ```typescript
209
+ <HeroSection
210
+ heading={{ en: 'Welcome', fr: 'Bienvenue' }}
211
+ description={{ en: 'Start your journey', fr: 'Commencez votre voyage' }}
212
+ cta={{
213
+ text: { en: 'Get Started', fr: 'Commencer' },
214
+ href: '/contact'
215
+ }}
216
+ locale={locale}
217
+ />
218
+ ```
219
+
220
+ ### Utility Function
221
+
222
+ Get the right language:
223
+
224
+ ```typescript
225
+ import { getLocalizedString } from '@zoyth/simple-site-framework';
226
+
227
+ const text = getLocalizedString(
228
+ { en: 'Hello', fr: 'Bonjour' },
229
+ locale
230
+ );
231
+ // Returns 'Hello' if locale is 'en'
232
+ // Returns 'Bonjour' if locale is 'fr'
233
+ // Falls back to default locale if locale not found
234
+ ```
235
+
236
+ ## Next.js Integration
237
+
238
+ ### App Router Structure
239
+
240
+ ```
241
+ src/app/
242
+ [locale]/
243
+ layout.tsx # Locale-aware layout
244
+ page.tsx # Homepage
245
+ about/
246
+ page.tsx # About page
247
+ services/
248
+ page.tsx # Services page
249
+ ```
250
+
251
+ ### Layout Setup
252
+
253
+ ```typescript
254
+ // src/app/[locale]/layout.tsx
255
+ import { i18nConfig } from '@/config/i18n';
256
+ import { LanguageSelector } from '@zoyth/simple-site-framework';
257
+
258
+ export async function generateStaticParams() {
259
+ return i18nConfig.locales.map((locale) => ({ locale }));
260
+ }
261
+
262
+ export default function LocaleLayout({
263
+ children,
264
+ params: { locale }
265
+ }: {
266
+ children: React.ReactNode;
267
+ params: { locale: string };
268
+ }) {
269
+ return (
270
+ <html lang={locale} dir={isRtlLocale(locale) ? 'rtl' : 'ltr'}>
271
+ <body>
272
+ <Header>
273
+ <LanguageSelector currentLocale={locale} />
274
+ </Header>
275
+ {children}
276
+ </body>
277
+ </html>
278
+ );
279
+ }
280
+ ```
281
+
282
+ ### Page Example
283
+
284
+ ```typescript
285
+ // src/app/[locale]/about/page.tsx
286
+ import { aboutContent } from '@/config/content/about';
287
+ import { AboutSection } from '@zoyth/simple-site-framework';
288
+
289
+ export default function AboutPage({
290
+ params: { locale }
291
+ }: {
292
+ params: { locale: string };
293
+ }) {
294
+ return <AboutSection {...aboutContent} locale={locale} />;
295
+ }
296
+ ```
297
+
298
+ ## Middleware Setup
299
+
300
+ Create middleware for automatic redirection and language detection:
301
+
302
+ ```typescript
303
+ // src/middleware.ts
304
+ import { createI18nMiddleware } from '@zoyth/simple-site-framework/lib/i18n';
305
+ import { i18nConfig } from './config/i18n';
306
+
307
+ export default createI18nMiddleware(i18nConfig);
308
+
309
+ export const config = {
310
+ matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
311
+ };
312
+ ```
313
+
314
+ **What it does:**
315
+ 1. Detects locale from URL, cookie, or browser
316
+ 2. Redirects to appropriate URL based on `localePrefix` mode
317
+ 3. Sets locale cookie for persistence
318
+ 4. Validates locale is supported
319
+
320
+ ## SEO Optimization
321
+
322
+ ### Meta Tags
323
+
324
+ Add language alternates:
325
+
326
+ ```typescript
327
+ // src/app/[locale]/page.tsx
328
+ import { I18nMetaTags } from '@zoyth/simple-site-framework';
329
+
330
+ export default function Page({ params: { locale } }) {
331
+ return (
332
+ <>
333
+ <I18nMetaTags
334
+ currentLocale={locale}
335
+ pathname="/about"
336
+ baseUrl="https://yoursite.com"
337
+ />
338
+ {/* Page content */}
339
+ </>
340
+ );
341
+ }
342
+ ```
343
+
344
+ Generates:
345
+ ```html
346
+ <link rel="canonical" href="https://yoursite.com/about" />
347
+ <link rel="alternate" hrefLang="en" href="https://yoursite.com/about" />
348
+ <link rel="alternate" hrefLang="fr" href="https://yoursite.com/fr/about" />
349
+ <link rel="alternate" hrefLang="x-default" href="https://yoursite.com/about" />
350
+ <meta property="og:locale" content="en" />
351
+ <meta property="og:locale:alternate" content="fr" />
352
+ ```
353
+
354
+ ### Sitemap Generation
355
+
356
+ Generate locale-specific sitemaps:
357
+
358
+ ```typescript
359
+ // src/app/sitemap.ts
360
+ import { i18nConfig } from '@/config/i18n';
361
+
362
+ export default function sitemap() {
363
+ const pages = ['', 'about', 'services', 'contact'];
364
+
365
+ return pages.flatMap(page =>
366
+ i18nConfig.locales.map(locale => ({
367
+ url: `https://yoursite.com/${locale !== 'en' ? `${locale}/` : ''}${page}`,
368
+ lastModified: new Date(),
369
+ changeFrequency: 'weekly',
370
+ priority: page === '' ? 1.0 : 0.8,
371
+ alternates: {
372
+ languages: Object.fromEntries(
373
+ i18nConfig.locales.map(l => [
374
+ l,
375
+ `https://yoursite.com/${l !== 'en' ? `${l}/` : ''}${page}`
376
+ ])
377
+ )
378
+ }
379
+ }))
380
+ );
381
+ }
382
+ ```
383
+
384
+ ## Content Management
385
+
386
+ ### Pattern 1: Separate Files per Locale
387
+
388
+ ```
389
+ src/content/
390
+ en/
391
+ home.ts
392
+ about.ts
393
+ fr/
394
+ home.ts
395
+ about.ts
396
+ ```
397
+
398
+ ```typescript
399
+ // src/content/en/home.ts
400
+ export const homeContent = {
401
+ hero: {
402
+ heading: 'Welcome to Our Site',
403
+ description: 'We help businesses grow'
404
+ }
405
+ };
406
+
407
+ // src/content/fr/home.ts
408
+ export const homeContent = {
409
+ hero: {
410
+ heading: 'Bienvenue sur notre site',
411
+ description: 'Nous aidons les entreprises à croître'
412
+ }
413
+ };
414
+
415
+ // Usage
416
+ import { homeContent as homeContentEn } from '@/content/en/home';
417
+ import { homeContent as homeContentFr } from '@/content/fr/home';
418
+
419
+ const content = locale === 'en' ? homeContentEn : homeContentFr;
420
+ ```
421
+
422
+ ### Pattern 2: Unified LocalizedStrings
423
+
424
+ ```typescript
425
+ // src/content/home.ts
426
+ export const homeContent = {
427
+ hero: {
428
+ heading: {
429
+ en: 'Welcome to Our Site',
430
+ fr: 'Bienvenue sur notre site'
431
+ },
432
+ description: {
433
+ en: 'We help businesses grow',
434
+ fr: 'Nous aidons les entreprises à croître'
435
+ }
436
+ }
437
+ };
438
+
439
+ // Usage - pass locale to component
440
+ <HeroSection {...homeContent.hero} locale={locale} />
441
+ ```
442
+
443
+ ### Pattern 3: CMS Integration
444
+
445
+ ```typescript
446
+ // Fetch localized content from CMS
447
+ async function getContent(slug: string, locale: string) {
448
+ const response = await fetch(
449
+ `https://cms.yoursite.com/api/content/${slug}?locale=${locale}`
450
+ );
451
+ return response.json();
452
+ }
453
+
454
+ // Use in page
455
+ export default async function Page({ params: { locale, slug } }) {
456
+ const content = await getContent(slug, locale);
457
+ return <HeroSection {...content.hero} locale={locale} />;
458
+ }
459
+ ```
460
+
461
+ ## Language Selector
462
+
463
+ The framework provides an adaptive language selector:
464
+
465
+ ```typescript
466
+ import { LanguageSelector } from '@zoyth/simple-site-framework';
467
+
468
+ <LanguageSelector
469
+ currentLocale={locale}
470
+ variant="auto" // 'text' for 2 languages, 'dropdown' for 3+
471
+ />
472
+ ```
473
+
474
+ **Automatic behavior:**
475
+ - 2 languages → Simple text toggle
476
+ - 3+ languages → Dropdown menu
477
+ - Generates URLs based on `localePrefix` mode
478
+ - Sets cookie on language change
479
+ - Handles slug translations
480
+
481
+ ## Advanced Features
482
+
483
+ ### RTL Language Support
484
+
485
+ ```typescript
486
+ export const i18nConfig: I18nConfig = {
487
+ locales: ['en', 'ar', 'he'],
488
+ defaultLocale: 'en',
489
+ rtlLocales: ['ar', 'he'],
490
+ };
491
+
492
+ // Apply to layout
493
+ <html lang={locale} dir={getTextDirection(locale)}>
494
+ ```
495
+
496
+ ### Slug Translations
497
+
498
+ Translate URL slugs:
499
+
500
+ ```typescript
501
+ // src/config/slug-translations.ts
502
+ export const slugTranslations = {
503
+ '/about': {
504
+ en: '/about',
505
+ fr: '/a-propos',
506
+ es: '/acerca-de'
507
+ },
508
+ '/services': {
509
+ en: '/services',
510
+ fr: '/services',
511
+ es: '/servicios'
512
+ }
513
+ };
514
+ ```
515
+
516
+ ### Date & Number Formatting
517
+
518
+ ```typescript
519
+ import { formatDate, formatNumber, formatCurrency } from '@zoyth/simple-site-framework/lib/i18n';
520
+
521
+ // Dates
522
+ formatDate(new Date(), 'fr', { dateStyle: 'long' });
523
+ // → "15 janvier 2026"
524
+
525
+ // Numbers
526
+ formatNumber(1234567.89, 'fr');
527
+ // → "1 234 567,89"
528
+
529
+ // Currency
530
+ formatCurrency(99.99, 'fr', 'EUR');
531
+ // → "99,99 €"
532
+ ```
533
+
534
+ ## Best Practices
535
+
536
+ ### ✅ Do
537
+
538
+ - Use LocalizedString for all user-facing text
539
+ - Set up middleware for automatic detection
540
+ - Include hreflang tags for SEO
541
+ - Test with actual users of each language
542
+ - Use professional translation services
543
+ - Keep locale switching visible and accessible
544
+
545
+ ### ❌ Don't
546
+
547
+ - Hardcode text in component files
548
+ - Forget to add new locales to all LocalizedStrings
549
+ - Use machine translation without review
550
+ - Assume all languages read left-to-right
551
+ - Forget to translate meta tags and alt text
552
+ - Use flags to represent languages (accessibility issue)
553
+
554
+ ## Migration from Hardcoded Locales
555
+
556
+ If upgrading from the old hardcoded `['fr', 'en']` system:
557
+
558
+ 1. Create i18n config file
559
+ 2. Set `locales: ['fr', 'en']` to match previous behavior
560
+ 3. Keep `localePrefix: 'always'` for identical URLs
561
+ 4. Test thoroughly before changing `localePrefix`
562
+
563
+ ## Troubleshooting
564
+
565
+ ### Wrong language displaying
566
+
567
+ **Check:**
568
+ 1. `locale` prop is being passed to components
569
+ 2. LocalizedString has entry for that locale
570
+ 3. Middleware is configured correctly
571
+ 4. Cookie/browser detection working
572
+
573
+ ### Language selector not appearing
574
+
575
+ **Check:**
576
+ 1. LanguageSelector is in layout
577
+ 2. `currentLocale` prop is provided
578
+ 3. More than 1 locale in i18nConfig
579
+
580
+ ### SEO tags missing
581
+
582
+ **Check:**
583
+ 1. I18nMetaTags component is used
584
+ 2. baseUrl is correct
585
+ 3. pathname matches actual route
586
+
587
+ ## Related Documentation
588
+
589
+ - **[Configuration-Driven](../core-concepts/configuration-driven.md)** - Content organization patterns
590
+ - **[LanguageSelector](../components/layout/LanguageSelector.md)** - Language switcher component
591
+ - **[SEO](./seo.md)** - Search engine optimization
592
+
593
+ ## API Reference
594
+
595
+ Full i18n utilities: **[API Reference](../api/utilities.md#i18n)**
@@ -0,0 +1,77 @@
1
+ # Performance
2
+
3
+ Performance optimization features for fast page loads and great Core Web Vitals.
4
+
5
+ ## Overview
6
+
7
+ The framework provides several built-in performance features:
8
+
9
+ - Server Components by default (zero client JS)
10
+ - Lazy loading for below-the-fold content
11
+ - Code splitting with dynamic imports
12
+ - Image optimization via Next.js Image
13
+ - Minimal bundle size
14
+
15
+ ## Key Concepts
16
+
17
+ Most framework components are Server Components, meaning they ship zero JavaScript to the browser. Only interactive components (marked as Client Components) add to the JS bundle.
18
+
19
+ ## Topics
20
+
21
+ - [Lazy Loading](./lazy-loading.md) - Defer loading of non-critical content
22
+ - [Image Optimization](./image-optimization.md) - Optimize images for web
23
+ - [Code Splitting](./code-splitting.md) - Split bundles for faster loads
24
+ - [Caching](./caching.md) - Caching strategies
25
+ - [Bundle Size](./bundle-size.md) - Minimize JavaScript bundle
26
+ - [Monitoring](./monitoring.md) - Measure and track performance
27
+
28
+ ## Quick Wins
29
+
30
+ ### Use LazySection
31
+
32
+ Wrap below-the-fold sections:
33
+
34
+ ```typescript
35
+ import { LazySection } from '@zoyth/simple-site-framework/components';
36
+
37
+ <HeroSection {...heroProps} /> {/* Above fold - load immediately */}
38
+
39
+ <LazySection> {/* Below fold - lazy loaded */}
40
+ <FeaturesGrid features={features} />
41
+ </LazySection>
42
+
43
+ <LazySection>
44
+ <TestimonialSection testimonials={testimonials} />
45
+ </LazySection>
46
+ ```
47
+
48
+ ### Prefer Server Components
49
+
50
+ ```typescript
51
+ // ✅ Server Component (default) - no client JS
52
+ import { HeroSection } from '@zoyth/simple-site-framework/components';
53
+
54
+ // ⚠️ Client Component - adds to JS bundle
55
+ 'use client';
56
+ import { AnalyticsTracker } from '@zoyth/simple-site-framework/client';
57
+ ```
58
+
59
+ ### Optimize Images
60
+
61
+ ```typescript
62
+ import Image from 'next/image';
63
+
64
+ <Image
65
+ src="/hero.jpg"
66
+ alt="Hero image"
67
+ width={1200}
68
+ height={600}
69
+ priority // Above-fold images
70
+ />
71
+ ```
72
+
73
+ ## See Also
74
+
75
+ - [Existing Performance Documentation](../../PERFORMANCE.md)
76
+ - [LazySection Component](../../components/LazySection.md)
77
+ - [AnimatedSection Component](../../components/AnimatedSection.md)