Skip to content
Twilight React Playground
ثيم رائدaren

shouldDehydrateQuery, isProductPreviewQuery

functionAdvancedserverbrowserlive demo

The engine's rule for which cached queries travel inside server-rendered HTML: successful and still-loading ones, never list-card previews.

import { shouldDehydrateQuery, isProductPreviewQuery } from '@salla.sa/twilight-theme-engine/api/product';

In plain words

When the server renders a page, the data it fetched is packed into the HTML so the browser does not fetch it again. This is called dehydration. shouldDehydrateQuery(query) decides, for each cached query, whether it is packed.

The engine's router already uses it. You need it only if you create a QueryClient of your own.

Signature

function shouldDehydrateQuery(query: Query): boolean
// !isProductPreviewQuery(query) && (defaultShouldDehydrateQuery(query) || query.state.status === 'pending')

function isProductPreviewQuery(query: { queryKey: readonly unknown[] }): boolean
// queryKey[0] === 'products' && queryKey[1] === 'preview'

Try it live

This browser's query cache, judged by the engine's dehydrate policy: what a server render would send with the HTML.Try this: open the product.list page, come back and read the cache again: its products preview entries stay behind.
Storefront canvas · en · LTR
Runs in the browser…
Controls
Only what would ship
What a theme writes
import { QueryClient } from '@tanstack/react-query';
import { shouldDehydrateQuery } from '@salla.sa/twilight-theme-engine/api/product';

// Only for a QueryClient you create yourself: createRouter() already uses this policy.
export const queryClient = new QueryClient({
  defaultOptions: {
    dehydrate: { shouldDehydrateQuery },
  },
});

Example

app/lib/queryClient.ts
import { QueryClient } from '@tanstack/react-query';
import { shouldDehydrateQuery } from '@salla.sa/twilight-theme-engine/api/product';

// Only for a QueryClient you create yourself: createRouter() already uses this policy.
export const queryClient = new QueryClient({
  defaultOptions: {
    dehydrate: { shouldDehydrateQuery },
  },
});

How it behaves

  • createRouter() builds its QueryClient with this policy, next to staleTime 60 s, gcTime 5 min, retry 1 and refetchOnWindowFocus: false.

  • Pending queries are included so a query still loading when the stream starts can finish in the browser. Failed queries stay out, as in TanStack Query's default.

  • Previews stay out because a card is a partial product; after hydration getProductPreview rebuilds them from the list queries that did travel.

Gotchas

  • Replacing it with () => true ships failed queries and list-card previews in the HTML. Extend it instead: (query) => shouldDehydrateQuery(query) || yourRule(query).

Related

Source and docs