fix: cart hydration warnings when promises resolve before hydration - #3983
Open
fredericoo wants to merge 1 commit into
Open
fix: cart hydration warnings when promises resolve before hydration#3983fredericoo wants to merge 1 commit into
fredericoo wants to merge 1 commit into
Conversation
fredericoo
force-pushed
the
fb-fix-cart-hydration-snapshot
branch
from
September 3, 2026 13:12
16f8a4b to
88bb6a1
Compare
fredericoo
marked this pull request as ready for review
September 3, 2026 13:13
fredericoo
force-pushed
the
fb-fix-cart-hydration-snapshot
branch
from
September 4, 2026 18:05
88bb6a1 to
8314811
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR: Cart data could settle before a retained client subtree hydrated, causing
useCartto render different client data from the server HTML.Before
useCartused the mutable live store for both client reads and React's server snapshot. Promise timing could therefore change the first hydration render and produce a mismatch on/cart.After
Plain
useCartconsumers hydrate from the provider's immutable initial snapshot, then update from the live store.useSuspenseCartkeeps a separate live selector so resolved cart content still streams without blocking the app shell.Hydration timing
This is not specifically a one-microtask delay. If async cart data has already settled, plain
useCartintentionally hydrates the loading or empty state that produced the server HTML, thenuseSyncExternalStorereconciles it to the live cart in a follow-up React update. React may complete that update before the browser paints.useSuspenseCartdoes not take that path. It reads the live store so streamed cart HTML hydrates against the resolved cart. The Next.js template uses this path forCartContent; plainuseCartremains appropriate for UI that can render from the initial snapshot and update immediately afterward.What this changes
CartProvider.useSuspenseCart.CartContentthrough its existing Suspense boundaries.Developer impact
No public API changes. Existing
useCartanduseSuspenseCartconsumers keep their current interfaces. Includes a patch changeset for@shopify/hydrogenbecause this fixes runtime hydration behavior.UX impact
Direct cart-page loads no longer log a recoverable hydration error or replace the server-rendered cart subtree. The app shell remains streamed and non-blocking.
Risk
How to Test
pnpm --filter @shopify/hydrogen build.pnpm --filter @shopify/hydrogen-template-nextjs dev:https.https://local.tryhydrogen.dev:5173/cartdirectly.