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

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,15 @@
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. Provides the perfect developer experience with automatic context detection, universal API, and zero configuration complexity.
4
4
 
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
5
+ **✨ Perfect DX Pattern:**
6
+ - **🎯 One Config File** - Single `lib/storefront.ts` using `createStorefront()`
7
+ - **🌍 Universal API** - Same `storefront()` import works everywhere
8
+ - **🔥 Automatic Tokens** - Creates and manages tokens automatically
9
+ - **🧠 Smart Context Detection** - Detects Server vs Client vs Build contexts
10
+ - **🍪 Cookie-based State** - Shared authentication via Next.js cookies
11
+ - **⚡ Request Isolation** - Proper per-request SDK instances on server
12
+ - **🛠 Zero Complexity** - Environment variables + one lib file = done
10
13
 
11
14
  ## Installation
12
15
 
@@ -18,23 +21,79 @@ pnpm add @commercengine/storefront-sdk-nextjs
18
21
 
19
22
  ## Quick Start
20
23
 
21
- ### 1. Initialize in your root layout
24
+ ### 1. Environment Variables (Required)
25
+
26
+ Add your store configuration to `.env.local`:
27
+
28
+ ```bash
29
+ NEXT_PUBLIC_STORE_ID=your-store-id
30
+ NEXT_PUBLIC_API_KEY=your-api-key
31
+ ```
32
+
33
+ **Optional environment variables:**
34
+ ```bash
35
+ # Environment (defaults to "staging")
36
+ NEXT_PUBLIC_ENVIRONMENT=staging # or "production"
37
+
38
+ # Custom API endpoint (overrides environment default)
39
+ NEXT_PUBLIC_API_BASE_URL=https://your-custom-api.example.com
40
+
41
+ # Request timeout in milliseconds
42
+ NEXT_PUBLIC_API_TIMEOUT=10000
43
+
44
+ # Debug mode (defaults to false)
45
+ NEXT_PUBLIC_DEBUG_MODE=true
46
+
47
+ # Default customer group for pricing and promotions
48
+ NEXT_PUBLIC_DEFAULT_CUSTOMER_GROUP_ID=01JHS28V83KDWTRBXXJQRTEKA0
49
+ ```
50
+
51
+ ### 2. Create Your Storefront Configuration
52
+
53
+ Create `lib/storefront.ts` in your project:
54
+
55
+ ```typescript
56
+ // lib/storefront.ts
57
+ import {
58
+ createStorefront,
59
+ type StorefrontRuntimeConfig,
60
+ } from "@commercengine/storefront-sdk-nextjs";
61
+
62
+ // Optional advanced configuration (everything not in environment variables)
63
+ const storefrontConfig: StorefrontRuntimeConfig = {
64
+ debug: true,
65
+ timeout: 15000,
66
+ logger: (msg: string, ...args: any[]) =>
67
+ console.log("[STOREFRONT]", msg, ...args),
68
+ onTokensUpdated: (access: string, refresh: string) => {
69
+ console.log("🔥 TOKENS UPDATED:", {
70
+ access: access.slice(0, 20) + "...",
71
+ refresh: refresh.slice(0, 20) + "...",
72
+ });
73
+ },
74
+ onTokensCleared: () => {
75
+ console.log("🔄 TOKENS CLEARED");
76
+ },
77
+ };
78
+
79
+ // Create the configured storefront function
80
+ export const storefront = createStorefront(storefrontConfig);
81
+
82
+ // Re-export types for convenience
83
+ export type { StorefrontRuntimeConfig };
84
+ ```
85
+
86
+ ### 3. Initialize in Root Layout
22
87
 
23
88
  ```typescript
24
89
  // app/layout.tsx
25
- import { StorefrontSDKInitializer, Environment } from '@commercengine/storefront-sdk-nextjs';
90
+ import { StorefrontSDKInitializer } from "@commercengine/storefront-sdk-nextjs/client";
26
91
 
27
92
  export default function RootLayout({ children }: { children: React.ReactNode }) {
28
93
  return (
29
- <html>
94
+ <html lang="en">
30
95
  <body>
31
- <StorefrontSDKInitializer
32
- config={{
33
- storeId: process.env.NEXT_PUBLIC_STORE_ID!,
34
- environment: Environment.Production,
35
- apiKey: process.env.NEXT_PUBLIC_API_KEY,
36
- }}
37
- />
96
+ <StorefrontSDKInitializer />
38
97
  {children}
39
98
  </body>
40
99
  </html>
@@ -42,198 +101,515 @@ export default function RootLayout({ children }: { children: React.ReactNode })
42
101
  }
43
102
  ```
44
103
 
45
- ### 2. Use anywhere - tokens created automatically!
104
+ ### 4. Use Anywhere with Universal Import
46
105
 
47
106
  ```typescript
48
- // Client Component - Just works
49
- 'use client';
50
- import { getStorefrontSDK } from '@commercengine/storefront-sdk-nextjs';
107
+ // Import your configured storefront everywhere
108
+ import { storefront } from "@/lib/storefront";
109
+ import { cookies } from "next/headers"; // Only for server contexts
51
110
 
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
- };
111
+ // Client Component - No cookies needed
112
+ const products = await storefront().catalog.listProducts();
113
+
114
+ // ✅ Server Component, Server Action, or API Route - MUST pass cookies
115
+ const products = await storefront(cookies()).catalog.listProducts();
116
+
117
+ // ✅ Root Layout - Special exception with explicit flag
118
+ const products = await storefront({ isRootLayout: true }).catalog.listProducts();
119
+
120
+ // ✅ SSG/ISR (build contexts) - Automatic fallback to memory storage
121
+ // (NEXT_BUILD_CACHE_TOKENS=true enables this)
122
+ const products = await storefront().catalog.listProducts();
123
+ ```
124
+
125
+ ## Usage in Different Next.js Contexts
62
126
 
63
- return <button onClick={handleAddToCart}>Add to Cart</button>;
127
+ ### Client Components
128
+
129
+ Client Components run in the browser and can persist tokens via cookies:
130
+
131
+ ```typescript
132
+ // components/ProductList.tsx
133
+ "use client";
134
+
135
+ import { useState, useEffect } from "react";
136
+ import { storefront } from "@/lib/storefront";
137
+
138
+ export default function ProductList() {
139
+ const [products, setProducts] = useState([]);
140
+
141
+ useEffect(() => {
142
+ async function loadProducts() {
143
+ const sdk = storefront(); // No cookies() needed on client-side
144
+
145
+ // Tokens are automatically managed by StorefrontSDKInitializer
146
+ const { data } = await sdk.catalog.listProducts();
147
+ if (data) setProducts(data.products);
148
+ }
149
+
150
+ loadProducts();
151
+ }, []);
152
+
153
+ return (
154
+ <div>
155
+ {products.map(product => (
156
+ <div key={product.id}>{product.name}</div>
157
+ ))}
158
+ </div>
159
+ );
64
160
  }
65
161
  ```
66
162
 
163
+ ### Server Components
164
+
165
+ Server Components run on the server and can read cookies:
166
+
67
167
  ```typescript
68
- // ✅ Server Action - Cookies required
69
- 'use server';
70
- import { cookies } from 'next/headers';
71
- import { getStorefrontSDK } from '@commercengine/storefront-sdk-nextjs';
168
+ // app/products/page.tsx
169
+ import { storefront } from "@/lib/storefront";
170
+ import { cookies } from "next/headers";
72
171
 
73
- export async function addToCartAction(productId: string) {
74
- const sdk = getStorefrontSDK(await cookies()); // Cookies needed on server
172
+ export default async function ProductsPage() {
173
+ const sdk = storefront(cookies());
75
174
 
76
- // Tokens automatically managed across server/client boundary! 🎉
77
- const { data } = await sdk.cart.addToCart({
78
- product_id: productId,
79
- quantity: 1,
80
- });
175
+ const { data: products } = await sdk.catalog.listProducts();
81
176
 
82
- return { success: true };
177
+ return (
178
+ <div>
179
+ {products?.products.map(product => (
180
+ <div key={product.id}>{product.name}</div>
181
+ ))}
182
+ </div>
183
+ );
83
184
  }
84
185
  ```
85
186
 
187
+ ### Server Actions
188
+
189
+ Server Actions can both read and write cookies, perfect for authentication:
190
+
86
191
  ```typescript
87
- // ✅ Server Component - Cookies required
88
- import { cookies } from 'next/headers';
89
- import { getStorefrontSDK } from '@commercengine/storefront-sdk-nextjs';
192
+ // app/actions.ts
193
+ "use server";
194
+
195
+ import { storefront } from "@/lib/storefront";
196
+ import { cookies } from "next/headers";
90
197
 
91
- export default async function ProductPage({ params }: { params: { id: string } }) {
92
- const sdk = getStorefrontSDK(await cookies());
198
+ export async function loginWithEmail(email: string, password: string) {
199
+ const sdk = storefront(cookies());
93
200
 
94
- // Anonymous tokens work perfectly for public data! 🎉
95
- const { data: product } = await sdk.catalog.getProduct({
96
- product_id_or_slug: params.id
97
- });
201
+ const { data, error } = await sdk.auth.loginWithPassword({ email, password });
202
+
203
+ if (data) {
204
+ // Tokens are automatically saved to cookies
205
+ return { success: true, user: data.user };
206
+ }
207
+
208
+ return { success: false, error: error?.message };
209
+ }
210
+ ```
211
+
212
+ ### API Routes
213
+
214
+ API Routes work identically to Server Actions:
215
+
216
+ ```typescript
217
+ // app/api/products/route.ts
218
+ import { storefront } from "@/lib/storefront";
219
+ import { cookies } from "next/headers";
220
+ import { NextResponse } from "next/server";
221
+
222
+ export async function GET() {
223
+ try {
224
+ const sdk = storefront(cookies());
225
+ const { data, error } = await sdk.catalog.listProducts();
226
+
227
+ if (error) {
228
+ return NextResponse.json({ error: error.message }, { status: 400 });
229
+ }
230
+
231
+ return NextResponse.json(data);
232
+ } catch (error) {
233
+ return NextResponse.json(
234
+ { error: "Internal server error" },
235
+ { status: 500 }
236
+ );
237
+ }
238
+ }
239
+ ```
240
+
241
+ ### Root Layout (Special Case)
242
+
243
+ Root Layout requires explicit flag since it's outside request context:
244
+
245
+ ```typescript
246
+ // app/layout.tsx
247
+ import { StorefrontSDKInitializer } from "@commercengine/storefront-sdk-nextjs/client";
248
+ import { storefront } from "@/lib/storefront";
98
249
 
99
- return <div>{product?.name}</div>;
250
+ // Root Layout requires explicit flag - no request context available
251
+ const sdk = storefront({ isRootLayout: true });
252
+ const { data: storeConfig } = await sdk.store.getStoreConfig();
253
+
254
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
255
+ return (
256
+ <html lang="en">
257
+ <body>
258
+ <StorefrontSDKInitializer />
259
+ <h1>Welcome to {storeConfig?.store_config?.brand.name}</h1>
260
+ {children}
261
+ </body>
262
+ </html>
263
+ );
100
264
  }
101
265
  ```
102
266
 
267
+ ## Static Site Generation (SSG) & Build-Time Optimization
103
268
 
104
- ## API Reference
269
+ The SDK provides powerful build-time optimizations through intelligent token caching.
105
270
 
106
- ### `getStorefrontSDK()`
271
+ ### Enable Build-Time Token Caching
107
272
 
108
- **Smart function** that works everywhere:
273
+ ```bash
274
+ # Enable caching during builds
275
+ NEXT_BUILD_CACHE_TOKENS=true pnpm build
276
+ ```
277
+
278
+ ### SSG with generateStaticParams
109
279
 
110
280
  ```typescript
111
- // ✅ Client-side (browser)
112
- const sdk = getStorefrontSDK();
281
+ // app/products/[slug]/page.tsx
282
+ import { storefront } from "@/lib/storefront";
283
+ import { notFound } from "next/navigation";
284
+
285
+ interface ProductPageProps {
286
+ params: Promise<{ slug: string }>;
287
+ }
113
288
 
114
- // Server-side (requires cookies for token persistence)
115
- const sdk = getStorefrontSDK(await cookies());
289
+ export default async function ProductPage({ params }: ProductPageProps) {
290
+ const { slug } = await params;
291
+ const sdk = storefront(); // No cookies() - uses build-time storage
292
+
293
+ const { data, error } = await sdk.catalog.getProductDetail({
294
+ product_id_or_slug: slug
295
+ });
296
+
297
+ if (error || !data) {
298
+ notFound();
299
+ }
300
+
301
+ return (
302
+ <div>
303
+ <h1>{data.product.name}</h1>
304
+ <p>SKU: {data.product.sku}</p>
305
+ <p>Description: {data.product.short_description}</p>
306
+ </div>
307
+ );
308
+ }
116
309
 
117
- // Server-side without cookies (helpful error message)
118
- const sdk = getStorefrontSDK(); // Throws clear error with instructions
310
+ // Generate static params from real API data
311
+ export async function generateStaticParams() {
312
+ const sdk = storefront(); // Token will be cached and reused
313
+
314
+ const { data: productsData, error } = await sdk.catalog.listProducts({
315
+ limit: 100
316
+ });
317
+
318
+ if (error || !productsData) {
319
+ return [];
320
+ }
321
+
322
+ return productsData.products.map(product => ({
323
+ slug: product.slug || product.id
324
+ }));
325
+ }
119
326
  ```
120
327
 
121
- ### `StorefrontSDKInitializer`
328
+ ### Build Performance Benefits
122
329
 
123
- **Lightweight initializer** (recommended for most apps):
330
+ With token caching enabled:
331
+ - ✅ Token created once and reused across all pages
332
+ - ✅ 100 pages = ~1 anonymous token API call total
333
+ - ✅ Faster builds, dramatically lower API usage
334
+
335
+ ## Authentication Patterns
336
+
337
+ ### Anonymous Users
338
+
339
+ The SDK automatically creates anonymous tokens:
124
340
 
125
341
  ```typescript
126
- <StorefrontSDKInitializer
127
- config={{
128
- storeId: "your-store-id",
129
- environment: Environment.Production, // or Environment.Staging
130
- apiKey: "your-api-key",
131
-
132
- // Optional: Advanced configuration
133
- tokenStorageOptions: {
134
- prefix: "ce_", // Cookie prefix (default)
135
- maxAge: 30 * 24 * 60 * 60, // 30 days
136
- secure: true, // Auto-detected from environment
137
- sameSite: "Lax",
138
- },
139
- }}
140
- />
342
+ // This works everywhere - creates anonymous token automatically
343
+ const { data: products } = await storefront(cookies()).catalog.listProducts();
344
+ ```
345
+
346
+ ### Email/Password Login
347
+
348
+ ```typescript
349
+ // Server Action
350
+ "use server";
351
+ export async function loginUser(email: string, password: string) {
352
+ const sdk = storefront(cookies());
353
+
354
+ const { data, error } = await sdk.auth.loginWithPassword({ email, password });
355
+
356
+ if (data) {
357
+ // Tokens automatically saved to cookies
358
+ redirect('/dashboard');
359
+ }
360
+
361
+ return { error: error?.message };
362
+ }
141
363
  ```
142
364
 
143
- ## Automatic Token Management 🤖
365
+ ### Phone/OTP Login
144
366
 
145
- The SDK now handles tokens **completely automatically**:
367
+ ```typescript
368
+ // Server Action - Step 1: Send OTP
369
+ export async function sendOTP(phone: string, country_code: string) {
370
+ const sdk = storefront(await cookies());
371
+
372
+ return await sdk.auth.loginWithPhone({
373
+ phone,
374
+ country_code,
375
+ register_if_not_exists: true
376
+ });
377
+ }
378
+
379
+ // Server Action - Step 2: Verify OTP
380
+ export async function verifyOTP(otp: string, otp_token: string, otp_action: string) {
381
+ const sdk = storefront(await cookies());
382
+
383
+ const { data, error } = await sdk.auth.verifyOtp({
384
+ otp,
385
+ otp_token,
386
+ otp_action
387
+ });
388
+
389
+ if (data) {
390
+ // Tokens automatically saved to cookies
391
+ return { success: true, user: data.user };
392
+ }
393
+
394
+ return { success: false, error: error?.message };
395
+ }
396
+ ```
146
397
 
147
- ### What Happens Automatically:
398
+ ## API Reference
148
399
 
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
400
+ ### `createStorefront(config?)`
155
401
 
156
- ### Zero Configuration Needed:
402
+ Creates a configured storefront function that works universally across all Next.js contexts.
157
403
 
158
404
  ```typescript
159
- // This just works - no token setup required!
160
- const sdk = getStorefrontSDK();
161
- const { data } = await sdk.catalog.listProducts(); // ✨ Tokens created automatically
405
+ import { createStorefront } from "@commercengine/storefront-sdk-nextjs";
406
+
407
+ export const storefront = createStorefront({
408
+ debug: true,
409
+ logger: (msg, ...args) => console.log('[DEBUG]', msg, ...args)
410
+ });
162
411
  ```
163
412
 
164
- ## Error Messages
413
+ **Parameters:**
414
+ - `config` (optional): `StorefrontRuntimeConfig` - Advanced configuration options
415
+
416
+ **Returns:**
417
+ - Universal `storefront()` function that works in all Next.js contexts
418
+
419
+ ### `StorefrontRuntimeConfig`
165
420
 
166
- ### Server Environment Detection
421
+ Optional configuration object for `createStorefront()`:
422
+
423
+ ```typescript
424
+ interface StorefrontRuntimeConfig {
425
+ // Override environment variables
426
+ storeId?: string;
427
+ apiKey?: string;
428
+ environment?: Environment;
429
+ baseUrl?: string;
430
+ timeout?: number;
431
+ debug?: boolean;
432
+
433
+ // Advanced options (not available via environment variables)
434
+ accessToken?: string;
435
+ refreshToken?: string;
436
+ defaultHeaders?: SupportedDefaultHeaders;
437
+ logger?: (message: string, ...args: any[]) => void;
438
+ onTokensUpdated?: (accessToken: string, refreshToken: string) => void;
439
+ onTokensCleared?: () => void;
440
+ tokenStorageOptions?: NextJSTokenStorageOptions;
441
+ }
167
442
  ```
168
- 🚨 Server Environment Detected!
169
443
 
170
- You're calling getStorefrontSDK() on the server without cookies.
171
- Please pass the Next.js cookie store:
444
+ ### Universal `storefront()` Function
172
445
 
173
- Correct usage:
174
- import { cookies } from 'next/headers';
446
+ The function returned by `createStorefront()` works in all contexts with strict enforcement:
175
447
 
176
- // Server Actions & Route Handlers
177
- const sdk = getStorefrontSDK(await cookies());
448
+ ```typescript
449
+ // Client-side (browser)
450
+ const sdk = storefront();
178
451
 
179
- // API Routes (Next.js 12)
180
- const sdk = getStorefrontSDK(cookies());
452
+ // Server-side (requires cookies for user continuity)
453
+ const sdk = storefront(cookies());
454
+
455
+ // Root Layout (special exception with explicit flag)
456
+ const sdk = storefront({ isRootLayout: true });
181
457
 
182
- Your current usage:
183
- const sdk = getStorefrontSDK(); // Missing cookies!
458
+ // Server-side without cookies - throws helpful error to protect user sessions
459
+ const sdk = storefront(); // Throws error in server contexts
184
460
  ```
185
461
 
186
- ## Migration from Base SDK
462
+ ### Function Signatures
187
463
 
188
- **Before (Base SDK):**
189
464
  ```typescript
190
- const sdk = new StorefrontSDK({ storeId: "...", tokenStorage: ... });
191
- await sdk.auth.getAnonymousToken(); // Manual token creation
192
- const { data } = await sdk.catalog.listProducts();
465
+ function storefront(): StorefrontSDK;
466
+ function storefront(cookieStore: NextCookieStore): StorefrontSDK;
467
+ function storefront(options: { isRootLayout: true }): StorefrontSDK;
468
+ function storefront(cookieStore: NextCookieStore, options: { isRootLayout?: boolean }): StorefrontSDK;
193
469
  ```
194
470
 
195
- **After (NextJS SDK):**
471
+ ### `StorefrontSDKInitializer`
472
+
473
+ Client-side initializer component (must be imported from `/client`):
474
+
196
475
  ```typescript
197
- const sdk = getStorefrontSDK(); // Environment detected automatically
198
- const { data } = await sdk.catalog.listProducts(); // Tokens created automatically!
476
+ import { StorefrontSDKInitializer } from "@commercengine/storefront-sdk-nextjs/client";
477
+
478
+ <StorefrontSDKInitializer />
199
479
  ```
200
480
 
201
- ## TypeScript Support
481
+ No props needed - configuration comes from environment variables and your `lib/storefront.ts` file.
482
+
483
+ ## Error Handling
202
484
 
203
- Full TypeScript support with all types from the base SDK:
485
+ All SDK methods return a consistent error structure:
204
486
 
205
487
  ```typescript
206
- import type {
207
- StorefrontSDK,
208
- NextJSSDKConfig,
209
- Environment
210
- } from '@commercengine/storefront-sdk-nextjs';
488
+ const { data, error, response } = await storefront(cookies()).catalog.listProducts();
489
+
490
+ if (error) {
491
+ console.error("API Error:", error.message, error.code);
492
+ console.log("Status:", response.status);
493
+ } else {
494
+ console.log("Products:", data.products);
495
+ }
211
496
  ```
212
497
 
213
498
  ## Best Practices
214
499
 
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
500
+ ### Do's
501
+
502
+ - **Set required environment variables**: `NEXT_PUBLIC_STORE_ID` and `NEXT_PUBLIC_API_KEY` are mandatory
503
+ - **Create one lib/storefront.ts file**: Use `createStorefront()` to configure advanced options
504
+ - **Initialize once**: Call `StorefrontSDKInitializer` only in your root layout
505
+ - **Use `storefront(cookies())`**: Always pass cookies in server contexts
506
+ - **Handle errors**: Always check the error property in responses
507
+ - **Use Server Actions**: For authentication flows that need to persist tokens
508
+
509
+ ### ❌ Don'ts
510
+
511
+ - **Don't call `cookies()` in Client Components**: It will throw an error
512
+ - **Don't initialize multiple times**: The SDK handles singleton behavior
513
+ - **Don't forget error handling**: API calls can fail for various reasons
514
+ - **Don't skip environment variables**: Missing required variables will cause errors
515
+
516
+ ## Troubleshooting
517
+
518
+ ### Common Issues
519
+
520
+ 1. **"Server context requires cookies for user continuity!"**
521
+ ```typescript
522
+ // ❌ Wrong - server context without cookies (breaks user sessions)
523
+ storefront()
524
+
525
+ // ✅ Correct - server context with cookies
526
+ storefront(cookies())
527
+
528
+ // ✅ Root Layout exception
529
+ storefront({ isRootLayout: true })
530
+ ```
531
+
532
+ 2. **Missing Environment Variables**
533
+ ```bash
534
+ # Ensure your .env.local has the required variables:
535
+ NEXT_PUBLIC_STORE_ID=your-store-id
536
+ NEXT_PUBLIC_API_KEY=your-api-key
537
+ ```
538
+
539
+ 3. **"Cookie store passed in client environment"**
540
+ ```typescript
541
+ // ❌ Wrong - client component with cookies
542
+ storefront(cookies())
543
+
544
+ // ✅ Correct - client component without cookies
545
+ storefront()
546
+ ```
547
+
548
+ 4. **Server Actions and async cookies()**
549
+ ```typescript
550
+ // ✅ Correct - Server Actions need await cookies()
551
+ const sdk = storefront(await cookies());
552
+
553
+ // ✅ Server Components and API Routes use cookies() directly
554
+ const sdk = storefront(cookies());
555
+ ```
556
+
557
+ ## Migration Guide
558
+
559
+ ### From Core SDK
560
+
561
+ ```typescript
562
+ // Before (core SDK)
563
+ import { StorefrontSDK } from "@commercengine/storefront-sdk";
564
+ const sdk = new StorefrontSDK({
565
+ storeId: "...",
566
+ tokenStorage: new BrowserTokenStorage()
567
+ });
568
+
569
+ // After (Next.js SDK)
570
+ import { storefront } from "@/lib/storefront";
571
+ const sdk = storefront(cookies());
572
+ ```
573
+
574
+ ### From Previous SDK Versions
220
575
 
221
- ## Why This Wrapper Exists
576
+ ```typescript
577
+ // Before (old pattern)
578
+ import { getStorefrontSDK, storefront } from "@commercengine/storefront-sdk-nextjs";
579
+ const sdk = getStorefrontSDK(cookies());
580
+ const sdk2 = storefront(cookies(), { debug: true });
581
+
582
+ // After (createStorefront pattern)
583
+ import { storefront } from "@/lib/storefront"; // Your configured function
584
+ const sdk = storefront(cookies());
585
+ ```
586
+
587
+ ## Why This Pattern?
588
+
589
+ **The Perfect DX Pattern provides:**
590
+ - **One Config File**: All advanced configuration in `lib/storefront.ts`
591
+ - **Environment Variables**: Basic config (storeId, apiKey) via env vars
592
+ - **Universal Import**: Same `storefront()` import everywhere
593
+ - **Strict User Continuity**: Enforces cookie passing to protect user sessions and analytics
594
+ - **Explicit Exceptions**: Clear patterns for special cases like Root Layout
595
+ - **Zero Guesswork**: Helpful errors guide developers to correct patterns
596
+
597
+ **Result: Production-ready e-commerce with bulletproof user session management!** 🛡️
598
+
599
+ ## API Reference
222
600
 
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
601
+ For complete API documentation of all available endpoints, visit [docs.commercengine.io/api-reference](https://docs.commercengine.io/api-reference)
228
602
 
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
603
+ The Next.js SDK provides access to all the same endpoints as the core SDK:
234
604
 
235
- **Result: Focus on your app, not SDK complexity!** 🚀
605
+ - `sdk.auth.*` - Authentication and user management
606
+ - `sdk.customer.*` - Customer profiles and preferences
607
+ - `sdk.catalog.*` - Products, categories, and search
608
+ - `sdk.cart.*` - Shopping cart management
609
+ - `sdk.order.*` - Order creation and tracking
610
+ - `sdk.shipping.*` - Shipping methods and rates
611
+ - `sdk.helpers.*` - Countries, currencies, utilities
236
612
 
237
613
  ## License
238
614
 
239
- All rights reserved - Commerce Engine
615
+ All Rights Reserved