@nexushub/client 0.8.9 → 1.1.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
@@ -1,1105 +1,63 @@
1
- # NexusHub Client SDK
1
+ # GN-Apex SDK 1.1.0
2
2
 
3
- <div align="center">
3
+ The GN-Apex SDK is the runtime layer for GN-Apex-generated sites. It is deliberately **zero developer configuration**: site developers focus on content, components and UI/UX while GN-Apex owns platform behavior.
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/@nexushub/client.svg?style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@nexushub/client)
6
- [![bundle size](https://img.shields.io/bundlephobia/minzip/@nexushub/client?style=for-the-badge&label=size)](https://bundlephobia.com/package/@nexushub/client)
7
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?style=for-the-badge&logo=typescript)](https://www.typescriptlang.org/)
8
- [![React](https://img.shields.io/badge/React-18%2B%2F19-blue?style=for-the-badge&logo=react)](https://reactjs.org/)
9
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=for-the-badge)](LICENSE)
5
+ ## Zero-config by design
10
6
 
11
- **The God-Tier Headless CMS SDK** — Everything you need to build blazing-fast websites with real-time content, analytics, and authentication.
7
+ ```ts
8
+ import { nexus } from "@nexushub/client";
12
9
 
13
- </div>
14
-
15
- ## ✨ Features
16
-
17
- ### 🚀 **Performance First**
18
-
19
- - **Multi-layer caching**: Memory → LocalStorage → Remote with LRU eviction
20
- - **Request optimization**: Batching, deduplication, exponential backoff
21
- - **Smart preloading**: Automatic content prediction and prefetching
22
- - **< 5ms** cache hits, **< 100ms** cold starts
23
-
24
- ### 📊 **Built-in Analytics Engine**
25
-
26
- - **Real-time tracking**: Page views, clicks, form submissions
27
- - **Web Vitals**: Core Web Vitals with RUM (Real User Monitoring)
28
- - **Session management**: 30-minute sessions with automatic renewal
29
- - **User identification**: Anonymous → Known user handshake
30
- - **E-commerce ready**: Track purchases, cart events, conversions
31
-
32
- ### 🔐 **Authentication System**
33
-
34
- - **Full auth flow**: Register, login, logout, social login (Google)
35
- - **Protected routes**: React hooks for auth state
36
- - **Session persistence**: HttpOnly cookies for security
37
- - **Role-based access**: User roles and permissions
38
-
39
- ### 📁 **Content Engine**
40
-
41
- - **Type-safe content**: Full TypeScript support with generics
42
- - **Advanced querying**: Filter, sort, paginate, search, include
43
- - **Real-time updates**: WebSocket/SSE subscriptions
44
- - **Collection support**: Dynamic content with rich relationships
45
- - **Singleton pages**: Static content with smart caching
46
-
47
- ### 🛠 **Developer Experience**
48
-
49
- - **Zero-config setup**: Auto-detects environment variables
50
- - **Local development**: Offline mode with local cache
51
- - **CLI tool**: Pull, seed, deploy, and manage content
52
- - **Debug mode**: Detailed logs and performance metrics
53
- - **Hot reload**: Instant updates during development
54
-
55
- ## 🚀 Quick Start
56
-
57
- ### 1. Installation
58
-
59
- ```bash
60
- npm install @nexushub/client
61
- # or
62
- yarn add @nexushub/client
63
- # or
64
- pnpm add @nexushub/client
65
- ```
66
-
67
- ### 2. Environment Setup
68
-
69
- Create `.env.local` in your project root:
70
-
71
- ```env
72
- # Required
73
- NEXT_PUBLIC_NEXUS_ID=your_project_id_here
74
- NEXT_PUBLIC_NEXUS_KEY=your_api_key_here
75
-
76
- # Optional (defaults to https://api.nexushub.com/v1)
77
- NEXT_PUBLIC_NEXUS_API_URL=https://api.nexushub.com/v1
78
- ```
79
-
80
- ### 3. Wrap Your App (Next.js/React)
81
-
82
- ```tsx
83
- // app/layout.tsx (Next.js App Router)
84
- import { NexusProvider } from '@nexushub/client'
85
-
86
- export default function RootLayout({
87
- children,
88
- }: {
89
- children: React.ReactNode
90
- }) {
91
- return (
92
- <html lang="en">
93
- <body>
94
- <NexusProvider>
95
- {children}
96
- </NexusProvider>
97
- </body>
98
- </html>
99
- )
100
- }
101
- ```
102
-
103
- ### 4. Use Content Anywhere
104
-
105
- ```tsx
106
- // app/page.tsx
107
- import { nexus } from '@nexushub/client'
108
-
109
- export default async function HomePage() {
110
- const homePage = await nexus.getPage('home')
111
- const blogPosts = await nexus.content.getCollection('blog_posts', {
112
- page: 1,
113
- limit: 10,
114
- sort: 'createdAt',
115
- order: 'desc',
116
- filter: { published: true }
117
- })
118
-
119
- return (
120
- <main>
121
- <h1>{homePage.title}</h1>
122
- <p>{homePage.content}</p>
123
-
124
- <h2>Latest Posts</h2>
125
- <ul>
126
- {blogPosts.items.map(post => (
127
- <li key={post.id}>
128
- <h3>{post.title}</h3>
129
- <p>{post.excerpt}</p>
130
- </li>
131
- ))}
132
- </ul>
133
- </main>
134
- )
135
- }
136
- ```
137
-
138
- ## 📖 Documentation
139
-
140
- ### Table of Contents
141
-
142
- 1. [Configuration](#configuration)
143
- 2. [Content Fetching](#content-fetching)
144
- 3. [Authentication](#authentication)
145
- 4. [Analytics](#analytics)
146
- 5. [Caching](#caching)
147
- 6. [CLI Tool](#cli-tool)
148
- 7. [API Reference](#api-reference)
149
- 8. [Examples](#examples)
150
- 9. [Troubleshooting](#troubleshooting)
151
-
152
- ## 🔧 Configuration
153
-
154
- ### Auto Configuration (Recommended)
155
-
156
- ```typescript
157
- // Uses environment variables automatically
158
- const client = nexus // Singleton instance
159
- ```
160
-
161
- ### Manual Configuration
162
-
163
- ```typescript
164
- import { createNexusClient } from '@nexushub/client'
165
-
166
- const client = createNexusClient({
167
- projectId: 'your-project-id',
168
- apiKey: 'your-api-key',
169
- apiUrl: 'https://api.nexushub.com/v1', // Optional
170
- debug: true, // Enable debug logging
171
- cacheStrategy: 'memory', // 'memory' | 'localStorage' | 'none'
172
- revalidateTime: 60, // Cache revalidation in seconds
173
- timeout: 10000, // Request timeout in ms
174
- retries: 3, // Number of retry attempts
175
- })
176
- ```
177
-
178
- ### React Configuration
179
-
180
- ```tsx
181
- // app/NexusWrapper.tsx
182
- 'use client'
183
-
184
- import { NexusProvider } from '@nexushub/client'
185
-
186
- export function NexusWrapper({ children }: { children: React.ReactNode }) {
187
- return (
188
- <NexusProvider projectId="optional-override-id">
189
- {children}
190
- </NexusProvider>
191
- )
192
- }
193
- ```
194
-
195
- ## 📁 Content Fetching
196
-
197
- ### Get a Single Page
198
-
199
- ```typescript
200
- // Basic usage
201
- const page = await nexus.getPage('home')
202
-
203
- // With options
204
- const page = await nexus.getPage('about', {
205
- revalidate: 300, // Revalidate every 5 minutes
206
- tags: ['page:about'], // Cache tags for invalidation
207
- forceRefresh: false, // Bypass cache
208
- includeMetadata: true, // Include cache metadata
209
- })
210
- ```
211
-
212
- ### Get Collections
213
-
214
- ```typescript
215
- // Get all items from a collection
216
- const posts = await nexus.content.getCollection('blog_posts')
217
-
218
- // Advanced querying
219
- const products = await nexus.content.getCollection('products', {
220
- page: 1,
221
- limit: 20,
222
- sort: 'price',
223
- order: 'asc',
224
- filter: {
225
- category: 'electronics',
226
- price: { $lt: 1000 },
227
- inStock: true
228
- },
229
- search: 'wireless headphones',
230
- fields: ['id', 'name', 'price', 'image'],
231
- include: ['category', 'reviews'],
232
- })
233
- ```
234
-
235
- ### Get a Single Item
236
-
237
- ```typescript
238
- const product = await nexus.content.getItem('products', 'prod_12345', {
239
- include: ['category', 'reviews', 'variants'],
240
- tags: ['product:prod_12345'],
241
- })
242
- ```
243
-
244
- ### Search Across Collections
245
-
246
- ```typescript
247
- const results = await nexus.content.search('wireless', {
248
- collections: ['products', 'articles'],
249
- fields: ['title', 'description', 'content'],
250
- limit: 50,
251
- })
252
- ```
253
-
254
- ### Get Global Settings
255
-
256
- ```typescript
257
- const globals = await nexus.content.getGlobals({
258
- include: ['navigation', 'footer', 'social_links'],
259
- revalidate: 3600, // Cache for 1 hour
260
- })
261
- ```
262
-
263
- ## 🔐 Authentication
264
-
265
- ### Setup Auth Provider
266
-
267
- ```tsx
268
- // app/auth/layout.tsx
269
- 'use client'
270
-
271
- import { useNexusAuth } from '@nexushub/client'
272
-
273
- export default function AuthLayout({ children }) {
274
- const { user, isLoading, isAuthenticated } = useNexusAuth()
275
-
276
- if (isLoading) return <div>Loading...</div>
277
-
278
- return (
279
- <div>
280
- {isAuthenticated ? (
281
- <div>
282
- <p>Welcome, {user.name}!</p>
283
- {children}
284
- </div>
285
- ) : (
286
- <LoginForm />
287
- )}
288
- </div>
289
- )
290
- }
10
+ const page = await nexus.getPage("home");
291
11
  ```
292
12
 
293
- ### Login/Register Forms
13
+ A GN-Apex deployment can inject runtime configuration through `window.__GNAPEX__` or meta tags. Environment variables remain supported as an escape hatch for Node/CI.
294
14
 
295
- ```tsx
296
- 'use client'
15
+ ## Automatic runtime behavior
297
16
 
298
- import { useNexusAuth } from '@nexushub/client'
299
- import { useState } from 'react'
17
+ By default the browser runtime automatically handles:
300
18
 
301
- export function LoginForm() {
302
- const { login, register, loginWithGoogle } = useNexusAuth()
303
- const [email, setEmail] = useState('')
304
- const [password, setPassword] = useState('')
305
-
306
- const handleLogin = async () => {
307
- try {
308
- await login({ email, password })
309
- // Redirect or show success
310
- } catch (error) {
311
- console.error('Login failed:', error)
312
- }
313
- }
314
-
315
- const handleGoogleLogin = () => {
316
- loginWithGoogle()
317
- }
318
-
319
- return (
320
- <div>
321
- <input
322
- type="email"
323
- value={email}
324
- onChange={(e) => setEmail(e.target.value)}
325
- placeholder="Email"
326
- />
327
- <input
328
- type="password"
329
- value={password}
330
- onChange={(e) => setPassword(e.target.value)}
331
- placeholder="Password"
332
- />
333
- <button onClick={handleLogin}>Login</button>
334
- <button onClick={handleGoogleLogin}>Login with Google</button>
335
- </div>
336
- )
337
- }
338
- ```
19
+ - page views and SPA navigation
20
+ - clicks, links, buttons, outbound links
21
+ - dead/rage clicks
22
+ - forms without collecting field values
23
+ - video lifecycle + 25/50/75/90/100% milestones
24
+ - scroll depth
25
+ - Web Vitals
26
+ - uncaught errors and unhandled rejections
27
+ - session/visitor identity
28
+ - offline IndexedDB event queue
29
+ - retry, batching, deduplication IDs and circuit breaking
30
+ - authentication synchronization
31
+ - push subscription synchronization (permission prompting remains platform/UX controlled)
32
+ - realtime content updates and cache invalidation
339
33
 
340
- ### Protected Routes Hook
34
+ Custom analytics calls are available as an escape hatch, not a requirement.
341
35
 
342
- ```tsx
343
- 'use client'
344
-
345
- import { useNexusAuth } from '@nexushub/client'
346
- import { useRouter } from 'next/navigation'
347
- import { useEffect } from 'react'
348
-
349
- export function useRequireAuth(redirectTo = '/login') {
350
- const { user, isLoading, isAuthenticated } = useNexusAuth()
351
- const router = useRouter()
352
-
353
- useEffect(() => {
354
- if (!isLoading && !isAuthenticated) {
355
- router.push(redirectTo)
356
- }
357
- }, [isLoading, isAuthenticated, router, redirectTo])
358
-
359
- return { user, isLoading }
360
- }
361
-
362
- // Usage
363
- export default function DashboardPage() {
364
- const { user, isLoading } = useRequireAuth('/login')
365
-
366
- if (isLoading) return <div>Loading...</div>
367
-
368
- return (
369
- <div>
370
- <h1>Dashboard</h1>
371
- <p>Welcome, {user.name}!</p>
372
- </div>
373
- )
374
- }
375
- ```
36
+ ## Cache model
376
37
 
377
- ## 📊 Analytics
38
+ GN-Apex intentionally defaults content revalidation to `false`. This is **not** a short-lived SDK cache. GN-Apex/Cloudflare owns invalidation and purge. Content can therefore be cached effectively forever until the platform purges affected resources.
378
39
 
379
- ### Automatic Tracking
40
+ The SDK still supports per-call revalidation for exceptional integrations, but production GN-Apex sites should normally leave the platform default untouched.
380
41
 
381
- Analytics starts automatically when you wrap your app with `NexusProvider`. It tracks:
382
-
383
- - Page views and route changes
384
- - Click events (links, buttons)
385
- - Form submissions
386
- - Web Vitals (CLS, LCP, FID, INP)
387
- - Performance metrics
388
- - Error tracking
389
-
390
- ### Manual Event Tracking
391
-
392
- ```typescript
393
- import { nexus } from '@nexushub/client'
394
-
395
- // Get analytics instance (automatically initialized)
396
- const analytics = nexus['analytics'] // Internal access
397
-
398
- // Or track custom events
399
- analytics.track('button_clicked', {
400
- button_id: 'cta-primary',
401
- page: '/home',
402
- timestamp: new Date().toISOString()
403
- })
404
-
405
- // Track purchases
406
- analytics.trackPurchase({
407
- order_id: 'ORD_12345',
408
- total: 99.99,
409
- currency: 'USD',
410
- items: [
411
- { id: 'prod_1', name: 'Product 1', price: 49.99, quantity: 2 }
412
- ]
413
- })
414
-
415
- // Identify users (link anonymous to known)
416
- await analytics.identify('user_123', {
417
- name: 'John Doe',
418
- email: 'john@example.com',
419
- plan: 'premium'
420
- })
421
- ```
42
+ ## Reliability
422
43
 
423
- ### Web Vitals Monitoring
44
+ The internal request pipeline provides request IDs, normalized errors, timeout handling, retry/backoff with jitter, rate limiting and circuit breaking. The request coalescer prevents duplicate concurrent reads for the same resource without incorrectly resolving unrelated requests with the same response.
424
45
 
425
- Automatically tracks Core Web Vitals with detailed breakdowns:
46
+ ## Platform features
426
47
 
427
- ```typescript
428
- // You can access vitals data through the analytics engine
429
- const sessionId = analytics.getSessionId()
430
- console.log('Session:', sessionId)
431
- ```
432
-
433
- ### Disable Analytics
434
-
435
- ```tsx
436
- // If you need to disable analytics (GDPR compliance)
437
- <NexusProvider disableAnalytics>
438
- {children}
439
- </NexusProvider>
440
- ```
441
-
442
- ## 💾 Caching System
443
-
444
- ### Cache Strategies
445
-
446
- ```typescript
447
- // 1. Memory Cache (Default - Fastest)
448
- const client = createNexusClient({
449
- cacheStrategy: 'memory', // In-memory cache, cleared on page refresh
450
- revalidateTime: 60 // Seconds
451
- })
452
-
453
- // 2. LocalStorage Cache (Persistent)
454
- const client = createNexusClient({
455
- cacheStrategy: 'localStorage', // Persists across sessions
456
- revalidateTime: 300 // 5 minutes
457
- })
458
-
459
- // 3. No Cache (Always Fresh)
460
- const client = createNexusClient({
461
- cacheStrategy: 'none' // Always fetch from network
462
- })
463
- ```
464
-
465
- ### Cache Invalidation
466
-
467
- ```typescript
468
- // Invalidate by tags
469
- nexus.content.invalidateCache(['page:home', 'collection:blog_posts'])
470
-
471
- // Clear all cache
472
- nexus.content.clearCache()
473
-
474
- // Manual cache control
475
- const page = await nexus.getPage('home', {
476
- forceRefresh: true, // Skip cache
477
- revalidate: 0 // No revalidation
478
- })
479
-
480
- // Get cache statistics
481
- const stats = nexus.content.getCacheStats()
482
- console.log(stats)
483
- /*
484
- {
485
- memory: {
486
- size: 15,
487
- hits: 124,
488
- misses: 12,
489
- hitRate: 0.91,
490
- evictions: 3
491
- },
492
- browser: { size: 24567 },
493
- local: { loaded: true }
494
- }
495
- */
496
- ```
48
+ The runtime exposes feature flags, remote configuration, diagnostics and a typed event bus for internal/platform integrations.
497
49
 
498
- ### Cache Tags
50
+ ## Security
499
51
 
500
- Auto-generated tags for smart invalidation:
52
+ Never expose a privileged server secret in browser configuration. Browser deployments should use the public GN-Apex credential model enforced by the platform. Analytics payloads redact common credential/secret fields when privacy redaction is enabled.
501
53
 
502
- ```typescript
503
- // Content gets tagged automatically:
504
- // - `nexus_project_${projectId}`
505
- // - `content_${slug}`
506
- // - `collection_${collectionId}`
507
- // - `item_${itemId}`
508
- // - `nexus_global_config`
509
-
510
- // You can add custom tags:
511
- const page = await nexus.getPage('home', {
512
- tags: ['homepage', 'featured']
513
- })
514
-
515
- // Later, invalidate all homepage content:
516
- nexus.content.invalidateCache(['homepage'])
517
- ```
518
-
519
- ## 🛠️ CLI Tool
520
-
521
- ### Installation
522
-
523
- ```bash
524
- # If installed globally
525
- npm install -g @nexushub/client
526
-
527
- # Or use npx
528
- npx @nexushub/client <command>
529
- ```
530
-
531
- ### Available Commands
532
-
533
- ```bash
534
- # Initialize project structure
535
- npx nexus init
536
-
537
- # Pull content from NexusHub to local cache
538
- npx nexus pull --api-key YOUR_KEY --project-id YOUR_ID
539
-
540
- # Seed content from local files to NexusHub
541
- npx nexus seed --input .nexus/seed
542
-
543
- # Trigger deployment
544
- npx nexus deploy --environment production
545
-
546
- # Check project status
547
- npx nexus status
548
-
549
- # Force overwrite local cache
550
- npx nexus pull --force
551
- ```
552
-
553
- ### Project Structure
554
-
555
- ```
556
- .nexus/
557
- ├── cache.json # Local cache (gitignored)
558
- ├── seed/ # Seed data for content
559
- │ ├── pages.json # Static pages
560
- │ ├── collections/ # Dynamic collections
561
- │ │ ├── blog_posts.json
562
- │ │ └── products.json
563
- │ └── globals.json # Global settings
564
- └── README.md
565
- ```
566
-
567
- ### Environment Variables for CLI
568
-
569
- ```bash
570
- # .env.local (for CLI)
571
- NEXUS_API_KEY=your_api_key_here
572
- NEXUS_PROJECT_ID=your_project_id_here
573
- NEXUS_API_URL=https://api.nexushub.com/v1
574
- ```
575
-
576
- ## 📚 API Reference
577
-
578
- ### `NexusClient`
579
-
580
- #### Constructor
581
-
582
- ```typescript
583
- new NexusClient(config?: Partial<NexusConfig>)
584
- ```
585
-
586
- #### Methods
587
-
588
- - `getPage<T>(slug: string, options?)`: Get singleton page
589
- - `getConfig()`: Get current config
590
- - `content`: ContentEngine instance
591
- - `analytics`: AnalyticsEngine instance (internal)
592
-
593
- ### `ContentEngine`
594
-
595
- #### Core Methods
596
-
597
- ```typescript
598
- // Content fetching
599
- getPage<T>(slug: string, options?): Promise<T>
600
- getCollection<T>(collectionId: string, query?, options?): Promise<CollectionResponse<T>>
601
- getItem<T>(collectionId: string, itemId: string, options?): Promise<T>
602
- getGlobals<T>(options?): Promise<T>
603
-
604
- // Search
605
- search<T>(query: string, options?): Promise<{ results: T[], total: number }>
606
-
607
- // Cache management
608
- invalidateCache(tags: string[]): void
609
- clearCache(): void
610
- getCacheStats(): CacheStats
611
-
612
- // Real-time
613
- subscribeToUpdates(callback): () => void
614
- prefetch(urls: string[]): Promise<void>
615
- ```
616
-
617
- ### `useNexusAuth()` Hook
618
-
619
- #### Returns
620
-
621
- ```typescript
622
- {
623
- user: SiteUser | null,
624
- isLoading: boolean,
625
- error: Error | null,
626
- isAuthenticated: boolean,
627
-
628
- // Methods
629
- login: (credentials: LoginCredentials) => Promise<void>,
630
- register: (credentials: RegisterCredentials) => Promise<void>,
631
- logout: () => Promise<void>,
632
- loginWithGoogle: () => void,
633
- updateProfile: (data: Partial<SiteUser>) => Promise<void>
634
- }
635
- ```
636
-
637
- ### Types
638
-
639
- ```typescript
640
- interface NexusConfig {
641
- projectId: string;
642
- apiUrl: string;
643
- apiKey?: string;
644
- debug?: boolean;
645
- cacheStrategy?: 'memory' | 'localStorage' | 'none';
646
- revalidateTime?: number;
647
- timeout?: number;
648
- retries?: number;
649
- }
650
-
651
- interface ContentResponse<T = any> {
652
- id: string;
653
- type: string;
654
- data: T;
655
- meta: {
656
- version: number;
657
- updatedAt: string;
658
- locale?: string;
659
- cacheStatus: 'hit' | 'miss' | 'stale';
660
- };
661
- }
662
-
663
- interface CollectionResponse<T = any> {
664
- items: T[];
665
- total: number;
666
- page: number;
667
- limit: number;
668
- totalPages: number;
669
- hasNext: boolean;
670
- hasPrev: boolean;
671
- meta?: {
672
- fetchedAt: string;
673
- cacheStatus: string;
674
- filters?: Record<string, any>;
675
- };
676
- }
677
- ```
678
-
679
- ## 🚦 Examples
680
-
681
- ### Next.js App Router
682
-
683
- ```tsx
684
- // app/layout.tsx
685
- import { NexusProvider } from '@nexushub/client'
686
-
687
- export default function RootLayout({ children }) {
688
- return (
689
- <html lang="en">
690
- <body>
691
- <NexusProvider>
692
- {children}
693
- </NexusProvider>
694
- </body>
695
- </html>
696
- )
697
- }
698
-
699
- // app/blog/page.tsx
700
- import { nexus } from '@nexushub/client'
701
-
702
- export default async function BlogPage() {
703
- const posts = await nexus.content.getCollection('blog_posts', {
704
- page: 1,
705
- limit: 10,
706
- sort: 'publishedAt',
707
- order: 'desc',
708
- filter: { status: 'published' }
709
- })
710
-
711
- return (
712
- <div>
713
- <h1>Blog</h1>
714
- {posts.items.map(post => (
715
- <article key={post.id}>
716
- <h2>{post.title}</h2>
717
- <p>{post.excerpt}</p>
718
- </article>
719
- ))}
720
- </div>
721
- )
722
- }
723
- ```
724
-
725
- ### Next.js Pages Router
726
-
727
- ```tsx
728
- // pages/_app.tsx
729
- import { NexusProvider } from '@nexushub/client'
730
-
731
- function MyApp({ Component, pageProps }) {
732
- return (
733
- <NexusProvider>
734
- <Component {...pageProps} />
735
- </NexusProvider>
736
- )
737
- }
738
-
739
- // pages/index.tsx
740
- import { nexus } from '@nexushub/client'
741
-
742
- export async function getServerSideProps() {
743
- const page = await nexus.getPage('home')
744
- return { props: { page } }
745
- }
746
-
747
- export default function Home({ page }) {
748
- return (
749
- <div>
750
- <h1>{page.title}</h1>
751
- <div dangerouslySetInnerHTML={{ __html: page.content }} />
752
- </div>
753
- )
754
- }
755
- ```
756
-
757
- ### React (No Framework)
758
-
759
- ```tsx
760
- // index.tsx
761
- import React from 'react'
762
- import ReactDOM from 'react-dom/client'
763
- import { NexusProvider } from '@nexushub/client'
764
- import App from './App'
765
-
766
- const root = ReactDOM.createRoot(document.getElementById('root'))
767
- root.render(
768
- <React.StrictMode>
769
- <NexusProvider projectId="your-project-id">
770
- <App />
771
- </NexusProvider>
772
- </React.StrictMode>
773
- )
774
-
775
- // App.tsx
776
- import { nexus, useNexusAuth } from '@nexushub/client'
777
- import { useEffect, useState } from 'react'
778
-
779
- function App() {
780
- const [page, setPage] = useState(null)
781
- const { user, login } = useNexusAuth()
782
-
783
- useEffect(() => {
784
- nexus.getPage('home').then(setPage)
785
- }, [])
786
-
787
- if (!page) return <div>Loading...</div>
788
-
789
- return (
790
- <div>
791
- <h1>{page.title}</h1>
792
- <p>{page.content}</p>
793
- </div>
794
- )
795
- }
796
- ```
797
-
798
- ### E-commerce Example
799
-
800
- ```tsx
801
- // components/ProductList.tsx
802
- import { nexus } from '@nexushub/client'
803
-
804
- export async function ProductList({ category }) {
805
- const products = await nexus.content.getCollection('products', {
806
- filter: { category },
807
- sort: 'createdAt',
808
- order: 'desc',
809
- include: ['variants', 'reviews']
810
- })
811
-
812
- const handlePurchase = (product) => {
813
- // Track purchase in analytics
814
- nexus['analytics'].trackPurchase({
815
- order_id: `temp_${Date.now()}`,
816
- total: product.price,
817
- currency: 'USD',
818
- items: [{
819
- id: product.id,
820
- name: product.name,
821
- price: product.price,
822
- quantity: 1
823
- }]
824
- })
825
- }
826
-
827
- return (
828
- <div className="grid grid-cols-4 gap-4">
829
- {products.items.map(product => (
830
- <div key={product.id} className="border p-4">
831
- <img src={product.image} alt={product.name} />
832
- <h3>{product.name}</h3>
833
- <p>${product.price}</p>
834
- <button
835
- onClick={() => handlePurchase(product)}
836
- className="bg-blue-500 text-white px-4 py-2"
837
- >
838
- Add to Cart
839
- </button>
840
- </div>
841
- ))}
842
- </div>
843
- )
844
- }
845
- ```
846
-
847
- ## 🐛 Troubleshooting
848
-
849
- ### Common Issues
850
-
851
- #### 1. "Missing projectId" Error
852
-
853
- ```bash
854
- # Check your environment variables
855
- echo $NEXT_PUBLIC_NEXUS_ID
856
-
857
- # Ensure .env.local exists
858
- ls -la .env.local
859
-
860
- # Restart dev server after changing env vars
861
- npm run dev
862
- ```
863
-
864
- #### 2. Cache Not Updating
865
-
866
- ```typescript
867
- // Force refresh
868
- await nexus.getPage('home', { forceRefresh: true })
869
-
870
- // Clear all cache
871
- nexus.content.clearCache()
872
-
873
- // Check cache stats
874
- console.log(nexus.content.getCacheStats())
875
- ```
876
-
877
- #### 3. Analytics Not Tracking
878
-
879
- ```typescript
880
- // Check if analytics is enabled
881
- const client = createNexusClient({ debug: true })
882
-
883
- // Verify in console logs
884
- // Should see: "[NexusHub] Analytics started"
885
- ```
886
-
887
- #### 4. Authentication Issues
888
-
889
- ```typescript
890
- // Check CORS settings in NexusHub dashboard
891
- // Ensure your domain is whitelisted
892
-
893
- // Verify HttpOnly cookies are supported
894
- // Some ad blockers may interfere
895
- ```
896
-
897
- #### 5. TypeScript Errors
898
-
899
- ```typescript
900
- // If you get "Property 'content' does not exist"
901
- // Make sure you're using the correct import:
902
- import { nexus } from '@nexushub/client' // Correct
903
- import nexus from '@nexushub/client' // Wrong
904
- ```
905
-
906
- ### Debug Mode
907
-
908
- Enable debug logging to see detailed information:
909
-
910
- ```typescript
911
- const client = createNexusClient({
912
- debug: true,
913
- cacheStrategy: 'memory'
914
- })
915
-
916
- // Check console for:
917
- // - Cache hits/misses
918
- // - Network requests
919
- // - Performance metrics
920
- // - Analytics events
921
- ```
922
-
923
- ### Performance Monitoring
924
-
925
- ```typescript
926
- // Get performance metrics
927
- const stats = nexus.content.getCacheStats()
928
- console.log('Cache Hit Rate:', stats.memory.hitRate)
929
-
930
- // Monitor Web Vitals in analytics dashboard
931
- // Visit: https://dashboard.nexushub.com/analytics
932
- ```
933
-
934
- ## 🔧 Advanced Configuration
935
-
936
- ### Custom Cache Implementation
937
-
938
- ```typescript
939
- import { MemoryCache, BrowserCache } from '@nexushub/client'
940
-
941
- // Extend existing cache
942
- class CustomMemoryCache extends MemoryCache {
943
- constructor(options) {
944
- super({ ...options, maxSize: 2000 })
945
- }
946
-
947
- set(key, data, options) {
948
- // Add custom logic
949
- console.log(`Caching: ${key}`)
950
- super.set(key, data, options)
951
- }
952
- }
953
-
954
- // Use in your app
955
- const customCache = new CustomMemoryCache({ ttl: 60000 })
956
- ```
957
-
958
- ### Middleware & Interceptors
959
-
960
- ```typescript
961
- // Request/Response interceptors
962
- const client = createNexusClient({
963
- interceptors: {
964
- request: (config) => {
965
- // Add custom headers
966
- config.headers['X-Custom-Header'] = 'value'
967
- return config
968
- },
969
- response: (response) => {
970
- // Transform response
971
- return response.data
972
- },
973
- error: (error) => {
974
- // Custom error handling
975
- console.error('Request failed:', error)
976
- throw error
977
- }
978
- }
979
- })
980
- ```
981
-
982
- ### Multiple Projects
983
-
984
- ```typescript
985
- import { createNexusClient } from '@nexushub/client'
986
-
987
- const mainClient = createNexusClient({
988
- projectId: 'main-project',
989
- apiKey: 'main-key'
990
- })
991
-
992
- const secondaryClient = createNexusClient({
993
- projectId: 'secondary-project',
994
- apiKey: 'secondary-key',
995
- apiUrl: 'https://api-2.nexushub.com/v1'
996
- })
997
-
998
- // Use both clients in your app
999
- const [mainPage, secondaryPage] = await Promise.all([
1000
- mainClient.getPage('home'),
1001
- secondaryClient.getPage('home')
1002
- ])
1003
- ```
1004
-
1005
- ## 📈 Performance Benchmarks
1006
-
1007
- ```
1008
- Cache Performance:
1009
- ├── Memory Cache: 0.1ms - 1ms
1010
- ├── LocalStorage: 1ms - 5ms
1011
- └── Network: 50ms - 300ms
1012
-
1013
- Bundle Size:
1014
- ├── Core SDK: 15kb gzipped
1015
- ├── With Analytics: 28kb gzipped
1016
- └── Full Package: 35kb gzipped
1017
-
1018
- Memory Usage:
1019
- ├── Memory Cache: ~5MB max
1020
- ├── LocalStorage: ~5MB max
1021
- └── Browser Memory: ~10MB typical
1022
- ```
1023
-
1024
- ## 🤝 Contributing
1025
-
1026
- We welcome contributions! Here's how to get started:
1027
-
1028
- 1. **Fork the repository**
1029
- 2. **Clone your fork**
1030
-
1031
- ```bash
1032
- git clone https://github.com/your-username/nexushub-client-sdk.git
1033
- cd nexushub-client-sdk/packages/client-sdk
1034
- ```
1035
-
1036
- 1. **Install dependencies**
54
+ ## Build
1037
55
 
1038
56
  ```bash
1039
57
  npm install
1040
- ```
1041
-
1042
- 1. **Run tests**
1043
-
1044
- ```bash
58
+ npm run type-check
1045
59
  npm test
1046
- npm run test:coverage
1047
- ```
1048
-
1049
- 1. **Make changes and test**
1050
-
1051
- ```bash
1052
- npm run dev # Watch mode
1053
- npm run build
1054
- ```
1055
-
1056
- 1. **Submit a Pull Request**
1057
-
1058
- ### Development Scripts
1059
-
1060
- ```bash
1061
- # Build
1062
60
  npm run build
1063
-
1064
- # Development (watch mode)
1065
- npm run dev
1066
-
1067
- # Type checking
1068
- npm run type-check
1069
-
1070
- # Linting
1071
- npm run lint
1072
-
1073
- # Testing
1074
- npm test # Run all tests
1075
- npm run test:watch # Watch mode
1076
- npm run test:coverage # Coverage report
1077
- npm run test:debug # Verbose output
1078
61
  ```
1079
62
 
1080
- ## 📄 License
1081
-
1082
- MIT License - see [LICENSE](LICENSE) file for details.
1083
-
1084
- ## 🔗 Links
1085
-
1086
- - [NexusHub Dashboard](https://dashboard.nexushub.com)
1087
- - [Documentation](https://docs.nexushub.com)
1088
- - [API Reference](https://docs.nexushub.com/api)
1089
- - [GitHub Issues](https://github.com/nexushub/client-sdk/issues)
1090
- - [Discord Community](https://discord.gg/nexushub)
1091
-
1092
- ## 🏆 Support
1093
-
1094
- - **Community Support**: [GitHub Discussions](https://github.com/nexushub/client-sdk/discussions)
1095
- - **Priority Support**: Available for enterprise plans
1096
- - **Bug Reports**: [GitHub Issues](https://github.com/nexushub/client-sdk/issues)
1097
- - **Feature Requests**: Submit via GitHub Issues
1098
-
1099
- ---
1100
-
1101
- <div align="center">
1102
- Made with ❤️ by the NexusHub Team
1103
- <br/>
1104
- <a href="https://nexushub.com">nexushub.com</a>
1105
- </div>
63
+ Before publishing, run the complete test/build pipeline in the target CI environment.