Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

TanStack · Component

HydrationBoundary

HydrationBoundary places previously dehydrated query state into a QueryClient for a rendered subtree. It merges overlapping data by freshness and always renders its children.

Since
v5

How it works

HydrationBoundary accepts dehydrated query state and makes it available through the relevant QueryClient while always rendering its children. New queries are incorporated during render; existing cached queries are updated after commit only when the dehydrated data is newer.

Syntax

<HydrationBoundary state={dehydratedState}>{children}</HydrationBoundary>

Parameters

NameTypeDescription
__namedParametersHydrationBoundaryPropsProps containing the dehydrated state and the children to render; the API also accepts optional hydration options and a custom QueryClient.

Returns

Element: the supplied children, rendered unconditionally.

Key points

  • The component transfers a serialized query-cache snapshot into the QueryClient available to descendants.
  • When cache entries overlap, freshness is decided from update timestamps instead of blindly replacing client data.
  • Its children are always rendered; the boundary does not gate rendering on completion of hydration.
  • Queries missing from the existing cache become available during the render phase, supporting server-rendered output.
  • Existing entries are updated after commit only if the dehydrated snapshot is fresher than the current cache.

Common mistakes

  • Mutations are not hydrated by this component; use the lower-level hydrate API or a persistence plugin when mutation hydration is required.
  • For queries already present in the cache, hydration occurs in an effect, so children can render once before fresher server data is applied.

Example: Hydrating prefetched server data

import { HydrationBoundary, dehydrate, QueryClient } from '@tanstack/react-query'

export default async function Page() {
  const queryClient = new QueryClient()
  await queryClient.prefetchQuery({
    queryKey: ['posts'],
    queryFn: fetchPosts,
  })

  return (
    <HydrationBoundary state={dehydrate(queryClient)}>
      <Posts />
    </HydrationBoundary>
  )
}

Prefetches server data, serializes the client cache, and provides it to the rendered subtree.

When to use it

Transfer prefetched query data from server to client

Server-rendered routes

Hydrate route data without blocking child rendering

Streaming or concurrent React applications

Apply fresher dehydrated results without overwriting newer client data

Client navigation with an existing cache

Interview questions

QWhat problem does HydrationBoundary solve?

It receives a dehydrated state, typically produced with dehydrate, and hydrates that state into the query client used by the component tree. Children render unconditionally rather than waiting for hydration.

Follow-up: What differs for queries already cached on the client? Only newer dehydrated data is applied, and it is applied in an effect after commit rather than during render.

QDoes HydrationBoundary hydrate mutations?

It hydrates queries but not mutations. Mutation hydration requires the lower-level hydrate API or the persistQueryClient plugin.

Follow-up: Why might a mutation not be visible after rendering a HydrationBoundary? Because the boundary deliberately handles query state only; mutation state must be restored separately.

QHow does hydration timing vary between new and existing queries?

When a query is absent from the client cache, its dehydrated state is hydrated during render. When it already exists, only fresher dehydrated data is applied after commit.

Follow-up: What user-visible effect can this timing cause? A child may briefly render with the existing cache value before the fresher dehydrated value arrives.

  • dehydrate
  • hydrate
  • QueryClient
  • QueryClientProvider
  • HydrateOptions
  • DehydratedState

Source: HydrationBoundary | TanStack Query React Docs. Checked 2026-10-15.