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