How to fix the data inconsistency between the shopping cart and checkout pages after updating next.js 16?
Update Next.js 16
Summary
- Previous Version: 15.3.0-canary.13
- Upgraded To: 16.0.5
- Package Manager: pnpm
- Status: ⚠️ Partially successful upgrade
my code : https://github.com/liaoyio/commerce/commit/12a2d6026f1feaf1e8f0982eee4932ecb5f2ae5f
Issues Requiring Manual Fixes
✅ Fixed: Experimental Flags Merged
File: next.config.ts
Issue: Next.js 16 merged experimental.ppr and experimental.useCache into experimental.cacheComponents
Before:
experimental: {
ppr: true,
inlineCss: true,
useCache: true
}After:
experimental: {
cacheComponents: true,
inlineCss: true
}✅ Fixed: Turbopack Flag Removed
File: package.json
Issue: Turbopack is now default in Next.js 16, the --turbopack flag is no longer needed
Before:
"dev": "next dev --turbopack"After:
"dev": "next dev"✅ Fixed: revalidateTag API Update
Files:
lib/shopify/index.ts
Issue: Next.js 16 recommends adding a profile parameter to revalidateTag() to achieve stale-while-revalidate behavior
Before:
revalidateTag(TAGS.collections);
revalidateTag(TAGS.products);After:
revalidateTag(TAGS.collections, 'max');
revalidateTag(TAGS.products, 'max');✅ Fixed: updateTag Usage in Server Actions
File: components/cart/actions.ts
Issue: Next.js 16 introduced the updateTag() API, specifically designed for Server Actions that require immediate data updates
Explanation:
| Feature | Next.js 15 revalidateTag() |
Next.js 16 revalidateTag() |
Next.js 16 updateTag() |
|---|---|---|---|
| Cache Invalidation | ✅ Immediate | ✅ Immediate | ✅ Immediate |
| Route Refresh | ✅ Auto-triggered | ❌ Not triggered | ✅ Auto-triggered |
| Page Re-render | ✅ Yes | ❌ No | ✅ Yes |
| Data Update Timing | Immediate | Delayed (SWR) | Immediate |
| Use Case | Server Actions | Route Handlers / Webhooks | Server Actions |
updateTag()immediately invalidates cache and triggers route refreshrevalidateTag(tag, 'max')uses stale-while-revalidate semantics and does not immediately trigger route refresh- In cart operations, using
updateTag()ensures users see updates immediately (e.g., cart modal display, cart count in header component)
Current Implementation:
// addItem removeItem and updateItemQuantity - use updateTag for immediate updates
updateTag(TAGS.cart);✅ Fixed: await params Hydration Error
- When page components directly
await paramsand include components usinguseSearchParams(), uncached data triggers errors; - Extract these async operations into separate components and wrap them with
Suspenseto avoid hydration errors and support streaming rendering; - Page components can immediately return Suspense boundaries without blocking rendering;
Current structure:
ProductPage (synchronous)
└─ Suspense
└─ ProductPageContent (async, await params)
└─ ProductProvider (uses useSearchParams)- This solves both the uncached data access issue with
paramsand the Suspense requirement foruseSearchParams().
Modified files: app/product/[handle]/page.tsx:52,133
✅ Fixed: Missing Suspense in Cache Components Mode
Issue: Hydration errors caused by missing Suspense in Cache Components mode.
Fix: Wrap components with Suspense
Total Updates: 2 locations
- 1 location in
components/layout/navbar/index.tsx:56,58 - 2 locations in
components/carousel.tsx:17,40
✅ Fixed: Cache Components Mode Build Error
Issue: In Next.js 16's Cache Components mode, the /[page] route is pre-rendered at build time, but CartProvider accessed an uncached cartPromise, causing blocking and build-time errors.
Fix
- Add cache directive to getCart()
- Add
'use cache: private'togetCart()inlib/shopify/index.ts - Each user has independent cache, avoiding build-time blocking
- Add
<Suspense>boundary in root layout
- Wrap
CartProvider'schildrenwith<Suspense>in app/layout.tsx - Ensure uncached data is accessed within
<Suspense>boundary
✅ Fixed: Cannot access Date.now() Hydration Error
Updated File components/layout/footer.tsx:11,16
After Change:
'use cache';
const menu = await getMenu('next-js-frontend-footer-menu');
const skeleton = 'w-full h-6 animate-pulse rounded-sm bg-neutral-200 dark:bg-neutral-700';
const currentYear = new Date().getFullYear();
const copyrightDate = 2023 + (currentYear > 2023 ? `-${currentYear}` : '');
const copyrightName = COMPANY_NAME || SITE_NAME || '';❌ Unfixed: Cart Quantity Update Issues with Rapid Consecutive Clicks
After upgrading from Next.js 15.3.0-canary.13 to 16.0.5, the following issues could not be resolved:
Issue 1: Cart quantity update operations behave abnormally when navigating to checkout page after rapid consecutive clicks.
- User rapidly clicks the "+" button 3 times
- 3 Server Actions start almost simultaneously
- Each Action calls
getCart(), potentially reading the same old data (e.g., quantity = 5) - Client-side payload is based on optimistic update:
item.quantity + 1= 6 - All 3 requests attempt to set quantity to 6, instead of the expected 8
- Final result: Quantity only increases by 1, instead of 3
https://github.com/user-attachments/assets/84aab1ab-c99f-4454-bae9-67f6847d7e90
Issue 2: Navigation to homepage after rapid consecutive cart quantity updates requires waiting for all server actions to complete before normal navigation can occur.
- User rapidly clicks the "+" button 3 times
- Closes the cart modal
- Immediately clicks the homepage logo to return to homepage
- Final result: Page is blocked and cannot directly return to homepage; navigation only works after all Server Actions complete
https://github.com/user-attachments/assets/7f907b9c-e7da-4d03-91f5-621485ea1f9c
This might be a business scenario issue, but my expected functionality is as follows:
When cart operations are clicked rapidly, if the checkout button is clicked, it should wait for all requests to complete before navigating to ensure checkout page reliability! Like this
When cart operations are clicked rapidly, if navigating to homepage or other pages, it should discard the existing request queue and navigate immediately; alternatively, is it possible to achieve non-blocking page navigation while cart data still updates normally?
Verified Functionality:
- ✅ Development server starts normally
- ✅ Page routing works normally
- ✅ Cart operation functionality works normally
- ❌ Navigation to checkout page after cart operations behaves abnormally
- ✅ Build succeeds, no compilation errors
- ✅ No linter errors
my code : https://github.com/liaoyio/commerce/commit/12a2d6026f1feaf1e8f0982eee4932ecb5f2ae5f
References
Source: vercel/commerce