@commercengine/storefront-sdk-nextjs 0.1.0-alpha.0 → 0.1.0-alpha.1

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,12 +1,14 @@
1
- # @commercengine/storefront-sdk-nextjs
1
+ # CommerceEngine Next.js SDK
2
2
 
3
- **Zero-config Next.js wrapper** for the Commerce Engine Storefront SDK. Handles server/client complexity automatically with smart token management.
3
+ **Production-ready Next.js wrapper** for the CommerceEngine Storefront SDK. Handles the complexities of Next.js runtime environments, automatic token management, and cookie-based authentication across all contexts.
4
4
 
5
5
  **✨ What makes this special:**
6
- - **🔥 Zero token management** - Tokens created automatically on first API call
7
- - **🧠 Smart environment detection** - One API works everywhere
8
- - **🍪 Cookie-based storage** - Seamless server/client token sync
9
- - **⚡ No setup required** - Just import and use
6
+ - **🎯 Universal API** - Single `storefront()` function works everywhere
7
+ - **🔥 Automatic Tokens** - Creates and manages tokens automatically
8
+ - **🧠 Smart Environment Detection** - Detects Server vs Client contexts
9
+ - **🍪 Cookie-based State** - Shared authentication via Next.js cookies
10
+ - **⚡ Request Isolation** - Proper per-request SDK instances on server
11
+ - **🛠 Zero Configuration** - Works with environment variables out of the box
10
12
 
11
13
  ## Installation
12
14
 
@@ -18,20 +20,32 @@ pnpm add @commercengine/storefront-sdk-nextjs
18
20
 
19
21
  ## Quick Start
20
22
 
21
- ### 1. Initialize in your root layout
23
+ ### 1. Environment Variables
24
+
25
+ Add your store configuration to `.env.local`:
26
+
27
+ ```bash
28
+ NEXT_PUBLIC_STORE_ID=your-store-id
29
+ NEXT_PUBLIC_ENVIRONMENT=staging # or "production"
30
+ NEXT_PUBLIC_API_KEY=your-api-key
31
+ ```
32
+
33
+ ### 2. Initialize in Root Layout
22
34
 
23
35
  ```typescript
24
36
  // app/layout.tsx
25
- import { StorefrontSDKInitializer, Environment } from '@commercengine/storefront-sdk-nextjs';
37
+ import { Environment, StorefrontSDKInitializer } from "@commercengine/storefront-sdk-nextjs/client";
26
38
 
27
39
  export default function RootLayout({ children }: { children: React.ReactNode }) {
28
40
  return (
29
- <html>
41
+ <html lang="en">
30
42
  <body>
31
- <StorefrontSDKInitializer
43
+ <StorefrontSDKInitializer
32
44
  config={{
33
- storeId: process.env.NEXT_PUBLIC_STORE_ID!,
34
- environment: Environment.Production,
45
+ storeId: process.env.NEXT_PUBLIC_STORE_ID || "",
46
+ environment: process.env.NEXT_PUBLIC_ENVIRONMENT === "production"
47
+ ? Environment.Production
48
+ : Environment.Staging,
35
49
  apiKey: process.env.NEXT_PUBLIC_API_KEY,
36
50
  }}
37
51
  />
@@ -42,87 +56,270 @@ export default function RootLayout({ children }: { children: React.ReactNode })
42
56
  }
43
57
  ```
44
58
 
45
- ### 2. Use anywhere - tokens created automatically!
59
+ ### 3. Use Anywhere with the Universal API
46
60
 
47
61
  ```typescript
48
- // Client Component - Just works
49
- 'use client';
50
- import { getStorefrontSDK } from '@commercengine/storefront-sdk-nextjs';
62
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
63
+ import { cookies } from "next/headers";
51
64
 
52
- export default function AddToCart({ productId }: { productId: string }) {
53
- const handleAddToCart = async () => {
54
- const sdk = getStorefrontSDK(); // No cookies needed on client
55
-
56
- // First API call automatically creates anonymous tokens! 🎉
57
- const { data } = await sdk.cart.addToCart({
58
- product_id: productId,
59
- quantity: 1,
60
- });
61
- };
65
+ // Client Component - No cookies needed
66
+ const products = await storefront().catalog.listProducts();
67
+
68
+ // Server Component, Server Action, or API Route
69
+ const products = await storefront(cookies()).catalog.listProducts();
70
+ ```
71
+
72
+ ## Usage in Different Next.js Contexts
73
+
74
+ ### Server Components
75
+
76
+ Server Components run on the server and can **read** cookies but cannot **write** them. Each request gets its own SDK instance with independent token management.
62
77
 
63
- return <button onClick={handleAddToCart}>Add to Cart</button>;
78
+ ```typescript
79
+ // app/products/page.tsx
80
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
81
+ import { cookies } from "next/headers";
82
+
83
+ export default async function ProductsPage() {
84
+ const sdk = storefront(cookies());
85
+
86
+ // This will generate a new anonymous token for this request
87
+ // Note: Token cannot be persisted (cookies are read-only in Server Components)
88
+ const { data: products } = await sdk.catalog.listProducts();
89
+
90
+ return (
91
+ <div>
92
+ {products?.products.map(product => (
93
+ <div key={product.id}>{product.name}</div>
94
+ ))}
95
+ </div>
96
+ );
64
97
  }
65
98
  ```
66
99
 
100
+ ### Client Components
101
+
102
+ Client Components run in the browser and can both read and write cookies, enabling persistent authentication.
103
+
67
104
  ```typescript
68
- // ✅ Server Action - Cookies required
69
- 'use server';
70
- import { cookies } from 'next/headers';
71
- import { getStorefrontSDK } from '@commercengine/storefront-sdk-nextjs';
105
+ // components/ProductList.tsx
106
+ "use client";
107
+
108
+ import { useState, useEffect } from "react";
109
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
72
110
 
73
- export async function addToCartAction(productId: string) {
74
- const sdk = getStorefrontSDK(await cookies()); // Cookies needed on server
111
+ export default function ProductList() {
112
+ const [products, setProducts] = useState([]);
113
+
114
+ useEffect(() => {
115
+ async function loadProducts() {
116
+ const sdk = storefront(); // No cookies() needed on client-side
117
+
118
+ // This will create and persist tokens via cookies
119
+ const { data } = await sdk.catalog.listProducts();
120
+ if (data) setProducts(data.products);
121
+ }
122
+
123
+ loadProducts();
124
+ }, []);
75
125
 
76
- // Tokens automatically managed across server/client boundary! 🎉
77
- const { data } = await sdk.cart.addToCart({
126
+ return (
127
+ <div>
128
+ {products.map(product => (
129
+ <div key={product.id}>{product.name}</div>
130
+ ))}
131
+ </div>
132
+ );
133
+ }
134
+ ```
135
+
136
+ ### Server Actions
137
+
138
+ Server Actions run on the server and can both read and write cookies, making them perfect for authentication flows.
139
+
140
+ ```typescript
141
+ // app/actions.ts
142
+ "use server";
143
+
144
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
145
+ import { cookies } from "next/headers";
146
+
147
+ export async function loginWithEmail(email: string, password: string) {
148
+ const sdk = storefront(cookies());
149
+
150
+ // This will create and persist tokens via cookies
151
+ const { data, error } = await sdk.auth.loginWithPassword({ email, password });
152
+
153
+ if (data) {
154
+ // Tokens are automatically saved to cookies by the SDK
155
+ return { success: true, user: data.user };
156
+ }
157
+
158
+ return { success: false, error: error?.message };
159
+ }
160
+
161
+ export async function addToCart(productId: string, quantity: number) {
162
+ const sdk = storefront(cookies());
163
+
164
+ // Uses existing authentication from cookies
165
+ const { data } = await sdk.cart.addItem({
78
166
  product_id: productId,
79
- quantity: 1,
167
+ quantity
80
168
  });
81
169
 
82
- return { success: true };
170
+ return data;
83
171
  }
84
172
  ```
85
173
 
174
+ ### API Routes
175
+
176
+ API Routes work identically to Server Actions - they can read and write cookies.
177
+
86
178
  ```typescript
87
- // ✅ Server Component - Cookies required
88
- import { cookies } from 'next/headers';
89
- import { getStorefrontSDK } from '@commercengine/storefront-sdk-nextjs';
179
+ // app/api/products/route.ts
180
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
181
+ import { cookies } from "next/headers";
182
+ import { NextResponse } from "next/server";
183
+
184
+ export async function GET() {
185
+ try {
186
+ const sdk = storefront(cookies());
187
+ const { data, error } = await sdk.catalog.listProducts();
188
+
189
+ if (error) {
190
+ return NextResponse.json({ error: error.message }, { status: 400 });
191
+ }
192
+
193
+ return NextResponse.json(data);
194
+ } catch (error) {
195
+ return NextResponse.json(
196
+ { error: "Internal server error" },
197
+ { status: 500 }
198
+ );
199
+ }
200
+ }
201
+
90
202
 
91
- export default async function ProductPage({ params }: { params: { id: string } }) {
92
- const sdk = getStorefrontSDK(await cookies());
203
+ ## Authentication Patterns
204
+
205
+ ### Anonymous Users
206
+
207
+ The SDK automatically creates anonymous tokens when needed:
208
+
209
+ ```typescript
210
+ // This works in any context - creates anonymous token automatically
211
+ const { data: products } = await storefront(cookies()).catalog.listProducts();
212
+ ```
213
+
214
+ ### Email/Password Login
215
+
216
+ ```typescript
217
+ // Server Action
218
+ "use server";
219
+ export async function loginUser(email: string, password: string) {
220
+ const sdk = storefront(cookies());
221
+
222
+ const { data, error } = await sdk.auth.loginWithPassword({ email, password });
223
+
224
+ if (data) {
225
+ // Tokens automatically saved to cookies
226
+ redirect('/dashboard');
227
+ }
228
+
229
+ return { error: error?.message };
230
+ }
231
+ ```
232
+
233
+ ### Phone/OTP Login
234
+
235
+ ```typescript
236
+ // Server Action - Step 1: Send OTP
237
+ export async function sendOTP(phone: string, country_code: string) {
238
+ const sdk = storefront(cookies());
93
239
 
94
- // Anonymous tokens work perfectly for public data! 🎉
95
- const { data: product } = await sdk.catalog.getProduct({
96
- product_id_or_slug: params.id
240
+ return await sdk.auth.loginWithPhone({
241
+ phone,
242
+ country_code,
243
+ register_if_not_exists: true
97
244
  });
245
+ }
98
246
 
99
- return <div>{product?.name}</div>;
247
+ // Server Action - Step 2: Verify OTP
248
+ export async function verifyOTP(otp: string, otp_token: string, otp_action: string) {
249
+ const sdk = storefront(cookies());
250
+
251
+ const { data, error } = await sdk.auth.verifyOtp({
252
+ otp,
253
+ otp_token,
254
+ otp_action
255
+ });
256
+
257
+ if (data) {
258
+ // Tokens automatically saved to cookies
259
+ return { success: true, user: data.user };
260
+ }
261
+
262
+ return { success: false, error: error?.message };
100
263
  }
101
264
  ```
102
265
 
266
+ ## Token Management & Cookie Behavior
267
+
268
+ ### How It Works
269
+
270
+ 1. **Server Components**: Generate tokens but can't persist them (read-only cookies)
271
+ 2. **Client Components**: Generate and persist tokens via `document.cookie`
272
+ 3. **Server Actions/API Routes**: Generate and persist tokens via Next.js `cookies()`
273
+ 4. **Shared State**: All contexts read from the same cookie storage
274
+
275
+ ### Cookie Configuration
276
+
277
+ The SDK uses secure cookies with sensible defaults:
278
+
279
+ ```typescript
280
+ // Advanced cookie configuration (optional)
281
+ <StorefrontSDKInitializer
282
+ config={{
283
+ storeId: "your-store-id",
284
+ apiKey: "your-api-key",
285
+ tokenStorageOptions: {
286
+ prefix: "ce_", // Cookie name prefix
287
+ maxAge: 30 * 24 * 60 * 60, // 30 days
288
+ path: "/",
289
+ secure: true, // HTTPS only (auto-detected)
290
+ sameSite: "Lax",
291
+ }
292
+ }}
293
+ />
294
+ ```
103
295
 
104
296
  ## API Reference
105
297
 
106
- ### `getStorefrontSDK()`
298
+ ### `storefront()`
107
299
 
108
- **Smart function** that works everywhere:
300
+ **Universal function** that works in all Next.js contexts:
109
301
 
110
302
  ```typescript
303
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
304
+ import { cookies } from "next/headers";
305
+
111
306
  // ✅ Client-side (browser)
112
- const sdk = getStorefrontSDK();
307
+ const sdk = storefront();
113
308
 
114
309
  // ✅ Server-side (requires cookies for token persistence)
115
- const sdk = getStorefrontSDK(await cookies());
310
+ const sdk = storefront(cookies());
116
311
 
117
312
  // ❌ Server-side without cookies (helpful error message)
118
- const sdk = getStorefrontSDK(); // Throws clear error with instructions
313
+ const sdk = storefront(); // Throws clear error with instructions
119
314
  ```
120
315
 
121
316
  ### `StorefrontSDKInitializer`
122
317
 
123
- **Lightweight initializer** (recommended for most apps):
318
+ **Client-side initializer** component (must be imported from `/client`):
124
319
 
125
320
  ```typescript
321
+ import { Environment, StorefrontSDKInitializer } from "@commercengine/storefront-sdk-nextjs/client";
322
+
126
323
  <StorefrontSDKInitializer
127
324
  config={{
128
325
  storeId: "your-store-id",
@@ -131,109 +328,414 @@ const sdk = getStorefrontSDK(); // Throws clear error with instructions
131
328
 
132
329
  // Optional: Advanced configuration
133
330
  tokenStorageOptions: {
134
- prefix: "ce_", // Cookie prefix (default)
135
- maxAge: 30 * 24 * 60 * 60, // 30 days
136
- secure: true, // Auto-detected from environment
331
+ prefix: "ce_", // Cookie prefix (default)
332
+ maxAge: 30 * 24 * 60 * 60, // 30 days
333
+ secure: true, // Auto-detected from environment
137
334
  sameSite: "Lax",
138
335
  },
139
336
  }}
140
337
  />
141
338
  ```
142
339
 
143
- ## Automatic Token Management 🤖
340
+ ## Error Handling
341
+
342
+ All SDK methods return a consistent error structure:
343
+
344
+ ```typescript
345
+ const { data, error, response } = await storefront(cookies()).catalog.listProducts();
346
+
347
+ if (error) {
348
+ console.error("API Error:", error.message, error.code);
349
+ console.log("Status:", response.status);
350
+ } else {
351
+ console.log("Products:", data.products);
352
+ }
353
+ ```
354
+
355
+ ## Static Site Generation (SSG) & Build-Time Optimization
144
356
 
145
- The SDK now handles tokens **completely automatically**:
357
+ The SDK provides powerful build-time optimizations for SSG/ISR that dramatically reduce API calls during the build process through intelligent token caching.
146
358
 
147
- ### What Happens Automatically:
359
+ ### Automatic Build-Time Token Caching
148
360
 
149
- 1. **First API Call**: Creates anonymous tokens seamlessly
150
- 2. **Token Expiry**: Refreshes tokens transparently
151
- 3. **Token Corruption**: Cleans up orphaned tokens
152
- 4. **User Login**: Upgrades from anonymous to authenticated tokens
153
- 5. **User Logout**: Downgrades gracefully with continuity
154
- 6. **Page Refresh**: Tokens persist via cookies across server/client
361
+ Enable automatic token caching during production builds:
155
362
 
156
- ### ✅ Zero Configuration Needed:
363
+ ```typescript
364
+ // next.config.ts
365
+ import type { NextConfig } from "next";
366
+ import { PHASE_PRODUCTION_BUILD } from 'next/constants';
367
+
368
+ const nextConfig = (phase: string): NextConfig => {
369
+ const isBuild = phase === PHASE_PRODUCTION_BUILD;
370
+
371
+ return {
372
+ env: {
373
+ // Enable build-time token caching during production builds
374
+ NEXT_BUILD_CACHE_TOKENS: process.env.NEXT_BUILD_CACHE_TOKENS ?? (isBuild ? 'true' : 'false'),
375
+ },
376
+ };
377
+ };
378
+
379
+ export default nextConfig;
380
+ ```
381
+
382
+ ### SSG with generateStaticParams
383
+
384
+ Create static product pages during build:
157
385
 
158
386
  ```typescript
159
- // This just works - no token setup required!
160
- const sdk = getStorefrontSDK();
161
- const { data } = await sdk.catalog.listProducts(); // ✨ Tokens created automatically
387
+ // app/products/[slug]/page.tsx
388
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
389
+ import { notFound } from "next/navigation";
390
+
391
+ interface ProductPageProps {
392
+ params: Promise<{ slug: string }>;
393
+ }
394
+
395
+ export default async function ProductPage({ params }: ProductPageProps) {
396
+ const { slug } = await params;
397
+ const sdk = storefront(); // No cookies() - uses build-time storage
398
+
399
+ // Get product detail by slug or ID
400
+ const { data, error } = await sdk.catalog.getProductDetail({
401
+ product_id_or_slug: slug
402
+ });
403
+
404
+ if (error || !data) {
405
+ notFound();
406
+ }
407
+
408
+ const { product } = data;
409
+
410
+ return (
411
+ <div>
412
+ <h1>{product.name}</h1>
413
+ <p>SKU: {product.sku}</p>
414
+ <p>Type: {product.product_type}</p>
415
+ <p>Description: {product.short_description}</p>
416
+ </div>
417
+ );
418
+ }
419
+
420
+ // Generate static params from real API data
421
+ export async function generateStaticParams() {
422
+ const sdk = storefront(); // No cookies() - uses build-time storage
423
+
424
+ const { data: productsData, error } = await sdk.catalog.listProducts({
425
+ limit: 100 // Generate pages for first 100 products
426
+ });
427
+
428
+ if (error || !productsData) {
429
+ console.error("Error fetching products for static generation:", error);
430
+ return [];
431
+ }
432
+
433
+ return productsData.products.map(product => ({
434
+ slug: product.slug || product.id
435
+ }));
436
+ }
162
437
  ```
163
438
 
164
- ## Error Messages
439
+ ### SSG Test Page Example
440
+
441
+ Create a page that makes multiple API calls during build to test token reuse:
442
+
443
+ ```typescript
444
+ // app/ssg-test/page.tsx
445
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
165
446
 
166
- ### Server Environment Detection
447
+ export default async function SSGTestPage() {
448
+ const sdk = storefront(); // No cookies() - uses build-time storage
449
+
450
+ // Make multiple API calls - token will be created once and reused
451
+ const { data: products, error: productsError } = await sdk.catalog.listProducts({
452
+ limit: 10
453
+ });
454
+
455
+ const { data: categories, error: categoriesError } = await sdk.catalog.listCategories({
456
+ nested_level: 1
457
+ });
458
+
459
+ const { data: anonymousToken, error: tokenError } = await sdk.auth.getAnonymousToken();
460
+
461
+ const buildTime = new Date().toISOString();
462
+
463
+ return (
464
+ <div>
465
+ <h1>SSG Test Page</h1>
466
+ <p><strong>Built at:</strong> {buildTime}</p>
467
+
468
+ <div>
469
+ <h2>Build-time API Results:</h2>
470
+
471
+ <div>
472
+ <h3>Products Call:</h3>
473
+ {productsError ? (
474
+ <p style={{ color: 'red' }}>Error: {productsError.message}</p>
475
+ ) : (
476
+ <p>✅ Success: Found {products?.products?.length || 0} products</p>
477
+ )}
478
+ </div>
479
+
480
+ <div>
481
+ <h3>Categories Call:</h3>
482
+ {categoriesError ? (
483
+ <p style={{ color: 'red' }}>Error: {categoriesError.message}</p>
484
+ ) : (
485
+ <p>✅ Success: Found {categories?.categories?.length || 0} categories</p>
486
+ )}
487
+ </div>
488
+
489
+ <div>
490
+ <h3>Anonymous Token Call:</h3>
491
+ {tokenError ? (
492
+ <p style={{ color: 'red' }}>Error: {tokenError.message}</p>
493
+ ) : (
494
+ <p>✅ Success: User ID {anonymousToken?.user?.id}</p>
495
+ )}
496
+ </div>
497
+ </div>
498
+ </div>
499
+ );
500
+ }
167
501
  ```
168
- 🚨 Server Environment Detected!
169
502
 
170
- You're calling getStorefrontSDK() on the server without cookies.
171
- Please pass the Next.js cookie store:
503
+ ### Build Performance Benefits
172
504
 
173
- Correct usage:
174
- import { cookies } from 'next/headers';
505
+ With token caching enabled, you'll see dramatic performance improvements:
175
506
 
176
- // Server Actions & Route Handlers
177
- const sdk = getStorefrontSDK(await cookies());
507
+ **Without Caching:**
508
+ - 🔴 Each page creates its own token
509
+ - 🔴 100 pages = 100+ anonymous token API calls
510
+ - 🔴 Slower builds, higher API usage
178
511
 
179
- // API Routes (Next.js 12)
180
- const sdk = getStorefrontSDK(cookies());
512
+ **With Caching:**
513
+ - Token created once and reused across all pages
514
+ - ✅ 100 pages = ~3 anonymous token API calls total
515
+ - ✅ Faster builds, dramatically lower API usage
181
516
 
182
- Your current usage:
183
- const sdk = getStorefrontSDK(); // Missing cookies!
517
+ ### Build Logs to Monitor
518
+
519
+ When build caching is working, you'll see these logs:
520
+
521
+ ```
522
+ 🚀 [BuildCache] Using BuildCachingMemoryTokenStorage with key: store:staging
523
+ 🟡 [BuildCache] No cached token found for key: store:staging
524
+ 🟠 [BuildCache] Caching new access token for key: store:staging
525
+ 🔵 [BuildCache] Using instance token for key: store:staging
526
+ 🟢 [BuildCache] Using cached token for key: store:staging
184
527
  ```
185
528
 
186
- ## Migration from Base SDK
529
+ **Key Indicators:**
530
+ - ✅ Only 1-3 "Automatically created anonymous session" messages
531
+ - ✅ Many "Using instance token" or "Using cached token" messages
532
+ - ✅ Minimal "Caching new access token" messages
533
+
534
+ ### Manual Override
535
+
536
+ You can manually control build caching:
537
+
538
+ ```bash
539
+ # Enable caching for this build
540
+ NEXT_BUILD_CACHE_TOKENS=true pnpm build
541
+
542
+ # Disable caching for this build
543
+ NEXT_BUILD_CACHE_TOKENS=false pnpm build
544
+ ```
545
+
546
+ ## Best Practices
547
+
548
+ ### ✅ Do's
549
+
550
+ - **Initialize once**: Call `StorefrontSDKInitializer` only in your root layout
551
+ - **Use `storefront(cookies())`**: Always pass cookies in server contexts
552
+ - **Handle errors**: Always check the error property in responses
553
+ - **Use Server Actions**: For authentication flows that need to persist tokens
554
+ - **Environment variables**: Store sensitive config in environment variables
555
+
556
+ ### ❌ Don'ts
557
+
558
+ - **Don't call `cookies()` in Client Components**: It will throw an error
559
+ - **Don't initialize multiple times**: The SDK handles singleton behavior
560
+ - **Don't forget error handling**: API calls can fail for various reasons
561
+ - **Don't rely on Server Component token persistence**: They can't write cookies
562
+
563
+ ## Troubleshooting
564
+
565
+ ### Common Issues
566
+
567
+ 1. **"Cookie store passed in client environment"**
568
+ ```typescript
569
+ // ❌ Wrong
570
+ storefront(cookies()) // in client component
571
+
572
+ // ✅ Correct
573
+ storefront() // in client component
574
+ ```
575
+
576
+ 2. **"SDK not initialized"**
577
+ ```typescript
578
+ // Make sure StorefrontSDKInitializer is in your root layout
579
+ <StorefrontSDKInitializer config={{ ... }} />
580
+ ```
581
+
582
+ 3. **"Cookies can only be modified in Server Action"**
583
+ This is expected behavior. Server Components can't persist tokens, but they can still make API calls with per-request tokens.
584
+
585
+ 4. **Server Environment Detection Error**
586
+ ```
587
+ 🚨 Server Environment Detected!
588
+
589
+ You're calling storefront() on the server without cookies.
590
+ Please pass the Next.js cookie store:
591
+
592
+ ✅ Correct usage:
593
+ import { cookies } from 'next/headers';
594
+ const sdk = storefront(cookies());
595
+
596
+ ❌ Your current usage:
597
+ const sdk = storefront(); // Missing cookies!
598
+ ```
599
+
600
+ ### Debug Mode
601
+
602
+ Enable detailed logging during development:
603
+
604
+ ```typescript
605
+ <StorefrontSDKInitializer
606
+ config={{
607
+ storeId: "your-store-id",
608
+ apiKey: "your-api-key",
609
+ debug: true, // Enable debug logging
610
+ }}
611
+ />
612
+ ```
613
+
614
+ ## Migration Guide
615
+
616
+ ### From Core SDK
187
617
 
188
- **Before (Base SDK):**
189
618
  ```typescript
190
- const sdk = new StorefrontSDK({ storeId: "...", tokenStorage: ... });
619
+ // Before (core SDK)
620
+ import { StorefrontSDK } from "@commercengine/storefront-sdk";
621
+ const sdk = new StorefrontSDK({
622
+ storeId: "...",
623
+ tokenStorage: new BrowserTokenStorage()
624
+ });
191
625
  await sdk.auth.getAnonymousToken(); // Manual token creation
192
- const { data } = await sdk.catalog.listProducts();
626
+
627
+ // After (Next.js SDK)
628
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
629
+ const sdk = storefront(cookies()); // Automatic token management
193
630
  ```
194
631
 
195
- **After (NextJS SDK):**
632
+ ### From Previous Next.js SDK Version
633
+
196
634
  ```typescript
197
- const sdk = getStorefrontSDK(); // Environment detected automatically
198
- const { data } = await sdk.catalog.listProducts(); // Tokens created automatically!
635
+ // Before (old pattern)
636
+ import { getStorefrontSDK } from "@commercengine/storefront-sdk-nextjs";
637
+ const sdk = getStorefrontSDK(cookies());
638
+
639
+ // After (new universal pattern)
640
+ import { storefront } from "@commercengine/storefront-sdk-nextjs";
641
+ const sdk = storefront(cookies());
199
642
  ```
200
643
 
201
644
  ## TypeScript Support
202
645
 
203
- Full TypeScript support with all types from the base SDK:
646
+ The SDK provides complete TypeScript support with auto-generated types:
204
647
 
205
648
  ```typescript
206
649
  import type {
207
650
  StorefrontSDK,
651
+ ApiResult,
652
+ UserInfo,
208
653
  NextJSSDKConfig,
209
654
  Environment
210
- } from '@commercengine/storefront-sdk-nextjs';
655
+ } from "@commercengine/storefront-sdk-nextjs";
656
+
657
+ // All API responses are properly typed
658
+ const { data }: ApiResult<ProductListResponse> = await storefront(cookies()).catalog.listProducts();
659
+
660
+ // IntelliSense works for all nested properties
661
+ console.log(data?.products[0].name);
211
662
  ```
212
663
 
213
- ## Best Practices
664
+ ## User Information
665
+
666
+ Get current user information from tokens:
667
+
668
+ ```typescript
669
+ const sdk = storefront(cookies());
670
+
671
+ const userInfo = await sdk.getUserInfo();
672
+ const isLoggedIn = await sdk.isLoggedIn();
673
+ const isAnonymous = await sdk.isAnonymous();
674
+ const userId = await sdk.getUserId();
675
+ const customerId = await sdk.getCustomerId();
676
+ ```
677
+
678
+ ## Advanced Usage
679
+
680
+ ### Custom Token Storage
681
+
682
+ ```typescript
683
+ import { TokenStorage } from "@commercengine/storefront-sdk-nextjs";
214
684
 
215
- 1. **✅ One-Line Setup**: `StorefrontSDKInitializer` in root layout is all you need
216
- 2. **✅ Server Cookies**: Always pass `await cookies()` on server-side
217
- 3. **✅ Error Handling**: Wrap API calls in try-catch
218
- 4. **✅ Environment Variables**: Use Next.js env vars for configuration
219
- 5. **⚡ Trust the Middleware**: No manual token management needed
685
+ class RedisTokenStorage implements TokenStorage {
686
+ async getAccessToken(): Promise<string | null> {
687
+ // Your Redis implementation
688
+ }
689
+
690
+ async setAccessToken(token: string): Promise<void> {
691
+ // Your Redis implementation
692
+ }
693
+
694
+ // ... implement other methods
695
+ }
696
+
697
+ // Use with the core SDK directly if needed
698
+ import { StorefrontSDK } from "@commercengine/storefront-sdk-nextjs";
699
+
700
+ const sdk = new StorefrontSDK({
701
+ storeId: "your-store-id",
702
+ apiKey: "your-api-key",
703
+ tokenStorage: new RedisTokenStorage(),
704
+ });
705
+ ```
220
706
 
221
707
  ## Why This Wrapper Exists
222
708
 
223
- **The base SDK is powerful but complex for Next.js:**
224
- - Manual token storage setup
225
- - Server/client environment handling
226
- - Cookie configuration for SSR
227
- - Token lifecycle management
709
+ **The core SDK is powerful but complex for Next.js:**
710
+ - Manual token storage setup and configuration
711
+ - Server/client runtime environment handling
712
+ - Cookie configuration for SSR/SSG
713
+ - Request isolation and per-request instances
714
+ - Next.js-specific execution model complexities
715
+
716
+ **This wrapper handles it all automatically:**
717
+ - Universal `storefront()` API that works everywhere
718
+ - Request-scoped server instances with React cache
719
+ - Cookie-based token persistence across boundaries
720
+ - Environment detection and configuration
721
+ - Build-time optimizations for SSG/ISR
722
+
723
+ **Result: Production-ready e-commerce with zero complexity!** 🚀
724
+
725
+ ## API Reference
726
+
727
+ For complete API documentation of all available endpoints, visit [docs.commercengine.io/api-reference](https://docs.commercengine.io/api-reference)
228
728
 
229
- **This wrapper makes it effortless:**
230
- - Zero configuration token management
231
- - Automatic environment detection
232
- - Cookie-based persistence works out of the box
233
- - One API that works everywhere
729
+ The Next.js SDK provides access to all the same endpoints as the core SDK:
234
730
 
235
- **Result: Focus on your app, not SDK complexity!** 🚀
731
+ - `sdk.auth.*` - Authentication and user management
732
+ - `sdk.customer.*` - Customer profiles and preferences
733
+ - `sdk.catalog.*` - Products, categories, and search
734
+ - `sdk.cart.*` - Shopping cart management
735
+ - `sdk.order.*` - Order creation and tracking
736
+ - `sdk.shipping.*` - Shipping methods and rates
737
+ - `sdk.helpers.*` - Countries, currencies, utilities
236
738
 
237
739
  ## License
238
740
 
239
- All rights reserved - Commerce Engine
741
+ All Rights Reserved