lynkow 2.1.3 → 3.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/README.md CHANGED
@@ -8,6 +8,9 @@ Official TypeScript SDK for [Lynkow](https://lynkow.com) Headless CMS.
8
8
  - **Type-safe** - Full TypeScript support with comprehensive types
9
9
  - **Framework-agnostic** - Works with Next.js, Nuxt, Astro, SvelteKit, etc.
10
10
  - **Tree-shakeable** - Only import what you need
11
+ - **Isomorphic** - Works on both browser and server (Node.js, Deno, Bun)
12
+ - **Built-in Analytics** - Page views, events, and funnel tracking
13
+ - **Cookie Consent** - GDPR-compliant consent banner with preferences
11
14
  - **Spam protection** - Built-in honeypot fields for form submissions
12
15
 
13
16
  ## Installation
@@ -23,9 +26,9 @@ pnpm add lynkow
23
26
  ## Quick Start
24
27
 
25
28
  ```typescript
26
- import { createLynkowClient } from 'lynkow'
29
+ import { createClient } from 'lynkow'
27
30
 
28
- const lynkow = createLynkowClient({
31
+ const lynkow = createClient({
29
32
  siteId: 'your-site-uuid',
30
33
  locale: 'fr', // optional default locale
31
34
  })
@@ -44,7 +47,7 @@ const post = await lynkow.contents.getBySlug('my-article')
44
47
  ## Configuration
45
48
 
46
49
  ```typescript
47
- interface LynkowConfig {
50
+ interface ClientConfig {
48
51
  // Required: Your site UUID
49
52
  siteId: string
50
53
 
@@ -56,13 +59,16 @@ interface LynkowConfig {
56
59
 
57
60
  // Optional: Custom fetch options (for Next.js cache, etc.)
58
61
  fetchOptions?: RequestInit
62
+
63
+ // Optional: Enable debug logging
64
+ debug?: boolean
59
65
  }
60
66
  ```
61
67
 
62
68
  ### Next.js App Router Example
63
69
 
64
70
  ```typescript
65
- const lynkow = createLynkowClient({
71
+ const lynkow = createClient({
66
72
  siteId: process.env.LYNKOW_SITE_ID!,
67
73
  locale: 'fr',
68
74
  fetchOptions: {
@@ -71,6 +77,20 @@ const lynkow = createLynkowClient({
71
77
  })
72
78
  ```
73
79
 
80
+ ## Browser vs Server
81
+
82
+ The SDK is isomorphic and works on both browser and server environments. Some features are browser-only:
83
+
84
+ | Feature | Browser | Server |
85
+ |---------|---------|--------|
86
+ | Contents, Categories, Pages... | ✅ | ✅ |
87
+ | Forms, Reviews | ✅ | ✅ |
88
+ | Analytics tracking | ✅ | ❌ (no-op) |
89
+ | Consent banner | ✅ | ❌ (no-op) |
90
+ | Branding badge | ✅ | ❌ (no-op) |
91
+ | Locale detection | ✅ | ✅ (returns default) |
92
+ | Cache | localStorage | In-memory |
93
+
74
94
  ## Services
75
95
 
76
96
  ### Contents (Blog Posts)
@@ -133,12 +153,12 @@ const jsonLd = await lynkow.pages.getJsonLd('about')
133
153
 
134
154
  ```typescript
135
155
  // Get site config with all global blocks
136
- const { data } = await lynkow.blocks.siteConfig()
156
+ const { data } = await lynkow.globals.siteConfig()
137
157
  const header = data.globals['header']
138
158
  const footer = data.globals['footer']
139
159
 
140
160
  // Get a specific global block
141
- const { data: header } = await lynkow.blocks.global('header')
161
+ const { data: header } = await lynkow.globals.global('header')
142
162
  ```
143
163
 
144
164
  ### Forms
@@ -192,16 +212,25 @@ console.log(config.defaultLocale) // 'fr'
192
212
 
193
213
  ### Legal Documents
194
214
 
215
+ Legal documents are pages tagged with `legal`. Use the legal service to retrieve them.
216
+
195
217
  ```typescript
196
- // List all legal documents
197
- const { data } = await lynkow.legal.list()
218
+ // List all legal documents (pages with 'legal' tag)
219
+ const docs = await lynkow.legal.list()
220
+ docs.forEach(doc => console.log(doc.slug, doc.name))
198
221
 
199
- // Get specific document
200
- const privacy = await lynkow.legal.getByType('privacy')
201
- const terms = await lynkow.legal.getByType('terms')
222
+ // Get specific document by slug
223
+ const privacy = await lynkow.legal.getBySlug('privacy-policy')
224
+ const terms = await lynkow.legal.getBySlug('terms-of-service')
225
+
226
+ // Access document content and SEO
227
+ console.log(privacy.data.content) // Rich text content
228
+ console.log(privacy.seo?.title) // SEO meta title
202
229
  ```
203
230
 
204
- ### Cookie Consent
231
+ ### Cookie Consent (Low-level)
232
+
233
+ For programmatic access to cookie configuration:
205
234
 
206
235
  ```typescript
207
236
  // Get cookie banner config
@@ -246,6 +275,175 @@ if (redirect) {
246
275
  }
247
276
  ```
248
277
 
278
+ ## Analytics (Browser-only)
279
+
280
+ The SDK includes built-in analytics that loads the Lynkow tracker automatically.
281
+
282
+ ```typescript
283
+ // Initialize analytics (called automatically on client creation)
284
+ await lynkow.analytics.init()
285
+
286
+ // Track page views
287
+ await lynkow.analytics.trackPageview()
288
+
289
+ // Track with custom data
290
+ await lynkow.analytics.trackPageview({
291
+ path: '/custom-path',
292
+ title: 'Custom Title',
293
+ referrer: 'https://google.com',
294
+ })
295
+
296
+ // Track custom events
297
+ await lynkow.analytics.trackEvent({
298
+ type: 'purchase',
299
+ amount: 99.99,
300
+ currency: 'EUR',
301
+ })
302
+
303
+ // Track funnel steps
304
+ await lynkow.analytics.trackFunnelStep({
305
+ funnelId: 'checkout',
306
+ funnelName: 'Checkout Flow',
307
+ stepNumber: 2,
308
+ stepName: 'payment',
309
+ })
310
+
311
+ // Enable/disable tracking
312
+ lynkow.analytics.disable()
313
+ lynkow.analytics.enable()
314
+
315
+ // Check status
316
+ lynkow.analytics.isEnabled() // true/false
317
+ lynkow.analytics.isInitialized() // true/false
318
+
319
+ // Access underlying tracker
320
+ const tracker = lynkow.analytics.getTracker()
321
+ ```
322
+
323
+ ## Consent Management (Browser-only)
324
+
325
+ GDPR-compliant cookie consent banner with full UI.
326
+
327
+ ```typescript
328
+ // Show consent banner
329
+ lynkow.consent.show()
330
+
331
+ // Hide consent banner
332
+ lynkow.consent.hide()
333
+
334
+ // Show preferences modal (for "Manage cookies" link)
335
+ lynkow.consent.showPreferences()
336
+
337
+ // Accept all cookies
338
+ lynkow.consent.acceptAll()
339
+
340
+ // Reject all optional cookies
341
+ lynkow.consent.rejectAll()
342
+
343
+ // Set specific categories
344
+ lynkow.consent.setCategories({
345
+ analytics: true,
346
+ marketing: false,
347
+ preferences: true,
348
+ })
349
+
350
+ // Check consent status
351
+ lynkow.consent.hasConsented() // true if user made a choice
352
+ lynkow.consent.getCategories() // { necessary: true, analytics: true, ... }
353
+
354
+ // Get consent configuration from API
355
+ const config = await lynkow.consent.getConfig()
356
+
357
+ // Reset consent (clear stored preferences)
358
+ lynkow.consent.reset()
359
+ ```
360
+
361
+ ### Consent Categories
362
+
363
+ | Category | Description | Can be disabled |
364
+ |----------|-------------|-----------------|
365
+ | `necessary` | Essential cookies | ❌ Always true |
366
+ | `analytics` | Analytics & tracking | ✅ |
367
+ | `marketing` | Advertising cookies | ✅ |
368
+ | `preferences` | User preferences | ✅ |
369
+
370
+ ### Listening to Consent Changes
371
+
372
+ ```typescript
373
+ lynkow.on('consent-changed', (categories) => {
374
+ console.log('Consent updated:', categories)
375
+
376
+ if (categories.analytics) {
377
+ // Initialize analytics tools
378
+ }
379
+ })
380
+ ```
381
+
382
+ ## Branding (Browser-only)
383
+
384
+ For sites on the free plan, a "Powered by Lynkow" badge is displayed.
385
+
386
+ ```typescript
387
+ // Manually inject badge (auto-injected if required by plan)
388
+ lynkow.branding.inject()
389
+
390
+ // Remove badge
391
+ lynkow.branding.remove()
392
+
393
+ // Check if badge is visible
394
+ lynkow.branding.isVisible() // true/false
395
+ ```
396
+
397
+ ## Events
398
+
399
+ Subscribe to SDK events for reactive updates.
400
+
401
+ ```typescript
402
+ // Subscribe to an event
403
+ const unsubscribe = lynkow.on('consent-changed', (categories) => {
404
+ console.log('Consent changed:', categories)
405
+ })
406
+
407
+ // Unsubscribe when done
408
+ unsubscribe()
409
+ ```
410
+
411
+ ### Available Events
412
+
413
+ | Event | Payload | Description |
414
+ |-------|---------|-------------|
415
+ | `consent-changed` | `ConsentCategories` | User consent preferences changed |
416
+ | `locale-changed` | `{ locale: string }` | Locale was changed |
417
+ | `ready` | `SiteConfig` | Client fully initialized |
418
+
419
+ ## Locale Management
420
+
421
+ ```typescript
422
+ // Get current locale
423
+ console.log(lynkow.locale) // 'fr'
424
+
425
+ // Get available locales
426
+ console.log(lynkow.availableLocales) // ['fr', 'en', 'es']
427
+
428
+ // Change locale
429
+ lynkow.setLocale('en')
430
+
431
+ // Locale detection (browser-only)
432
+ // Priority: localStorage > URL path > HTML lang > default
433
+ ```
434
+
435
+ ## Cache Management
436
+
437
+ The SDK caches API responses automatically.
438
+
439
+ ```typescript
440
+ // Clear all cached data
441
+ lynkow.clearCache()
442
+
443
+ // Destroy client and cleanup resources
444
+ lynkow.destroy()
445
+ ```
446
+
249
447
  ## Error Handling
250
448
 
251
449
  ```typescript
@@ -297,18 +495,77 @@ All types are exported for your convenience:
297
495
 
298
496
  ```typescript
299
497
  import type {
498
+ // Entities
300
499
  Content,
301
500
  ContentSummary,
302
501
  Category,
303
502
  Page,
304
503
  Form,
305
504
  Review,
505
+ Tag,
506
+
507
+ // Config
306
508
  LynkowConfig,
509
+ ClientConfig,
510
+ SiteConfig,
511
+
512
+ // Filters
307
513
  ContentsFilters,
308
- // ... and many more
514
+ ReviewsFilters,
515
+ PaginationOptions,
516
+
517
+ // Responses
518
+ PaginatedResponse,
519
+ PaginationMeta,
520
+
521
+ // Analytics
522
+ PageviewData,
523
+ EventData,
524
+ FunnelStepData,
525
+
526
+ // Consent
527
+ ConsentCategories,
528
+ CookieConfig,
529
+
530
+ // Events
531
+ EventName,
532
+ LynkowEvents,
309
533
  } from 'lynkow'
310
534
  ```
311
535
 
536
+ ## Migration from v2.x
537
+
538
+ ### Breaking Changes
539
+
540
+ 1. **Factory function renamed**: `createLynkowClient` → `createClient` (alias still available)
541
+ 2. **Blocks service renamed**: `blocks` → `globals` (alias still available)
542
+ 3. **New browser-only modules**: `analytics`, `consent`, `branding`
543
+
544
+ ### New Features in v3
545
+
546
+ - Analytics tracking with automatic tracker.js loading
547
+ - GDPR consent banner with preferences UI
548
+ - Event system for reactive updates
549
+ - Locale detection and management
550
+ - Built-in caching (localStorage in browser, memory on server)
551
+ - Debug logging option
552
+
553
+ ### Upgrade Steps
554
+
555
+ ```typescript
556
+ // v2.x
557
+ import { createLynkowClient } from 'lynkow'
558
+ const lynkow = createLynkowClient({ siteId: '...' })
559
+
560
+ // v3.x (recommended)
561
+ import { createClient } from 'lynkow'
562
+ const lynkow = createClient({ siteId: '...', debug: true })
563
+
564
+ // v3.x also supports the old name for backward compatibility
565
+ import { createLynkowClient } from 'lynkow'
566
+ const lynkow = createLynkowClient({ siteId: '...' })
567
+ ```
568
+
312
569
  ## License
313
570
 
314
571
  Proprietary - See [LICENSE](./LICENSE) for details.