Advanced SSR and Next.js
Purpose and Scope
This page explains how TanStack Query fits into advanced server rendering with Next.js, especially when React Server Components, the Next.js app router, streaming hydration, and classic Next.js page-router data loading appear in the same project. The goal is not to replace the basic Server Rendering and Hydration guide; it is to help you reason about the additional phases introduced by Server Components and the app router. TanStack Query still centers on a QueryClient, prefetched query data, dehydration, hydration, and framework-specific providers, but the place where each step runs becomes more important.
Sources: docs/framework/react/guides/advanced-ssr.md, examples/react/nextjs/src/pages/index.tsx
The advanced server rendering guide frames Server Components as another kind of framework loader. That phrase is useful because it keeps the React Query mental model stable: server-only work can prefetch data, and client/application work can consume that data through the cache. In the app router, a Server Component is guaranteed to run only on the server, including during page transitions. By contrast, a Client Component can run during the initial server-rendering pass and later in the browser, so QueryClientProvider setup belongs in a client boundary even when the route uses server-only data preparation.
Sources: docs/framework/react/guides/advanced-ssr.md
Relevant Source Files
docs/framework/react/guides/advanced-ssr.md- First-party React guide for advanced server rendering with streaming, Server Components, and the Next.js app router; it also defines the loader phase versus application phase terminology used by this page.packages/react-query-next-experimental/package.json- Package metadata for@tanstack/react-query-next-experimental, including its purpose, exports, peer dependency ranges, build scripts, and supported Next.js and React versions.packages/react-query-next-experimental/src/index.ts- Public entry point for the experimental Next.js integration package; it exportsReactQueryStreamedHydration.examples/react/nextjs/src/pages/index.tsx- Next.js page-router example showing SSG withQueryClient,prefetchQuery, anddehydratereturned fromgetStaticProps.
Core Rendering Model
The main terminology distinction is between the server/client environment and the Server Component/Client Component component type. Server Components are server-only. Client Components are not browser-only; they may render as part of the server pass and then hydrate or continue in the browser. The guide describes Server Components as happening during a loader phase and Client Components as happening during the application phase. For TanStack Query, that means data preparation and cache seeding can happen in server-only code, while observer-driven UI consumption still requires a provider in the application tree.
Sources: docs/framework/react/guides/advanced-ssr.md
The initial provider setup is deliberately similar to other React Query applications: create a QueryClient and wrap the application in QueryClientProvider. The advanced guide adds two important SSR constraints. First, it recommends a nonzero default staleTime, such as 60 * 1000, so data prefetched on the server is not immediately refetched on the client after hydration. Second, it separates server and browser QueryClient creation. On the server, a new client is created per request-like execution; in the browser, a shared client is reused to avoid recreating the cache if React suspends during the initial render.
Sources: docs/framework/react/guides/advanced-ssr.md
A typical app-router provider file is marked with 'use client' because QueryClientProvider relies on React context. The guide imports environmentManager, QueryClient, and QueryClientProvider from @tanstack/react-query, then defines makeQueryClient() and getQueryClient(). environmentManager.isServer() decides whether to allocate a fresh server-side client or reuse the browser-level singleton. This pattern is less about global state and more about preserving the correct cache lifetime for each runtime: isolated on the server, stable in the browser.
Sources: docs/framework/react/guides/advanced-ssr.md
Next.js Integration Paths
TanStack Query supports more than one Next.js rendering style. The repository example at examples/react/nextjs/src/pages/index.tsx demonstrates the page-router SSG path: getStaticProps() creates a QueryClient, awaits queryClient.prefetchQuery({ queryKey: ['posts', 10], queryFn: () => fetchPosts(10) }), and returns dehydratedState: dehydrate(queryClient) as a prop. That example is useful as a baseline because it shows the same core primitives used by advanced app-router flows: prefetch into a cache, serialize the cache, and let the client read hydrated data.
Sources: examples/react/nextjs/src/pages/index.tsx
The app-router flow changes where the loader-like work lives, not the fundamental cache contract. Instead of getStaticProps or getServerSideProps, Server Components can perform server-only preparation. The advanced guide explicitly compares Server Components with Next.js data-loading functions and Remix loaders, while noting that Server Components can do more than return data. For Query users, the safe simplification is to treat them as a richer loader phase. The application phase still needs a provider boundary, and any component using React Query hooks must be inside the client-side provider tree.
Sources: docs/framework/react/guides/advanced-ssr.md, examples/react/nextjs/src/pages/index.tsx
Streaming Hydration Package
The experimental package @tanstack/react-query-next-experimental exists specifically for hydration utilities in the Next.js app directory. Its package metadata describes it as Hydration utils for React Query in the NextJs app directory, declares @tanstack/react-query as a peer dependency, and supports Next.js major versions ^13 || ^14 || ^15 || ^16 with React ^18 || ^19. That positioning matters: it is not a replacement for the core React adapter; it layers Next.js app-directory streaming support on top of @tanstack/react-query.
Sources: packages/react-query-next-experimental/package.json
The public source entry point is intentionally small: packages/react-query-next-experimental/src/index.ts exports ReactQueryStreamedHydration from ./ReactQueryStreamedHydration. The package exports map exposes the root package entry and ./package.json, with modern import and require builds plus a custom source condition. For application developers, the important public name to look for is ReactQueryStreamedHydration; for package consumers and tooling, the metadata confirms the package is side-effect free and built with tsup against tsconfig.prod.json.
Sources: packages/react-query-next-experimental/src/index.ts, packages/react-query-next-experimental/package.json
System-to-Code Mapping
| Concern | Source-backed implementation signal | How to use it |
|---|---|---|
| App-router mental model | docs/framework/react/guides/advanced-ssr.md describes Server Components as a loader phase and Client Components as the application phase. | Put server-only data preparation in Server Components and keep React Query hook consumers under a client provider. |
| Provider setup | The guide imports environmentManager, QueryClient, and QueryClientProvider and creates separate server/browser client behavior. | Create a fresh server client and reuse a browser client, usually with default query staleTime above zero. |
| Page-router SSG | examples/react/nextjs/src/pages/index.tsx uses getStaticProps, prefetchQuery, and dehydrate. | Use this as the classic prefetch/dehydrate pattern when using the Next.js pages directory. |
| Streaming app-directory utility | packages/react-query-next-experimental/src/index.ts exports ReactQueryStreamedHydration. | Install the experimental package when you need the app-directory streaming hydration integration. |
Compact API and Package Reference
// React adapter primitives shown in the advanced SSR guide
import {
environmentManager,
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query'// Experimental Next.js app-directory entry point
export { ReactQueryStreamedHydration } from './ReactQueryStreamedHydration'// Page-router SSG pattern from the Next.js example
export async function getStaticProps() {
const queryClient = new QueryClient()
await queryClient.prefetchQuery({
queryKey: ['posts', 10],
queryFn: () => fetchPosts(10),
})
return {
props: {
dehydratedState: dehydrate(queryClient),
},
}
}The package reference has a few constraints worth checking before adopting the streaming helper. The package name is @tanstack/react-query-next-experimental; its root export is the public entry point; its peer dependencies require @tanstack/react-query, Next.js 13 through 16, and React 18 or 19. The package is marked sideEffects: false, publishes build output and source, and includes type-test scripts across multiple TypeScript versions. Those signals tell you the integration is packaged like the rest of the monorepo, while its name still communicates an experimental surface.
Sources: packages/react-query-next-experimental/package.json, packages/react-query-next-experimental/src/index.ts
Execution Flow and Next Steps
A practical advanced SSR setup usually proceeds in layers. Start with the provider boundary, because every React Query hook consumer depends on it. Configure the QueryClient with SSR-friendly defaults, especially a nonzero staleTime, and make sure server execution creates isolated clients while browser execution reuses a stable one. Next, decide which routing model you are using. In the pages router, follow the getStaticProps pattern: prefetch, dehydrate, pass the dehydrated state. In the app router, treat Server Components as the loader phase and use the appropriate hydration boundary for the client/application phase.
Sources: docs/framework/react/guides/advanced-ssr.md, examples/react/nextjs/src/pages/index.tsx
Read the general SSR and hydration material before applying these patterns broadly, then add the advanced guide when you introduce Server Components, app-router streaming, or the experimental Next.js hydration package. If your project only needs static page-router prefetching, the example flow may be sufficient. If your project uses the Next.js app directory and streaming, evaluate @tanstack/react-query-next-experimental and its ReactQueryStreamedHydration export alongside the normal @tanstack/react-query provider setup.
Sources: docs/framework/react/guides/advanced-ssr.md, packages/react-query-next-experimental/package.json, packages/react-query-next-experimental/src/index.ts