T
TanStack9mo ago
rare-sapphire

NextJS 15: HydrationBoundary not passing data to client component when prefetching

When i try to prefetch data in a layout or page.tsx, and then useQuery in the client component wrapped in a HydrationBoundary, the data is not loading on the page. It works fine if i remove the hydrationboundary wit hdehydrated state, but then im doing client side fetching, i want initial data to be server side QueryProvider:
"use client";

import {
QueryClient,
QueryClientProvider,
HydrationBoundary,
dehydrate,
} from "@tanstack/react-query";
import { PropsWithChildren, useState } from "react";

export default function QueryProvider({ children }: PropsWithChildren) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
refetchOnMount: false,
staleTime: 60 * 1000,
},
},
})
);

return (
<QueryClientProvider client={queryClient}>
<HydrationBoundary state={dehydrate(queryClient)}>
{children}
</HydrationBoundary>
</QueryClientProvider>
);
}
"use client";

import {
QueryClient,
QueryClientProvider,
HydrationBoundary,
dehydrate,
} from "@tanstack/react-query";
import { PropsWithChildren, useState } from "react";

export default function QueryProvider({ children }: PropsWithChildren) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
refetchOnMount: false,
staleTime: 60 * 1000,
},
},
})
);

return (
<QueryClientProvider client={queryClient}>
<HydrationBoundary state={dehydrate(queryClient)}>
{children}
</HydrationBoundary>
</QueryClientProvider>
);
}
root layout: import QueryProvider from "@/providers/QueryProvider"; import "./globals.css"; import Header from "./components/Header"; import { client } from "@/utils/client"; import { headers } from "next/headers"; import { authClient } from "@/utils/authClient"; import { SocketProvider } from "@/providers/SocketProvider"; export const metadata = { title: "Create Next App", description: "Generated by create next app", }; export default async function RootLayout({ children, }: { children: React.ReactNode; }) { const session = await authClient.getSession({ fetchOptions: { headers: await headers(), }, }); return ( <html lang="en"> <body className=""> <QueryProvider> <SocketProvider session={session?.data}>{children}</SocketProvider> </QueryProvider> </body> </html> ); }
The layout that i want to query data: its a sidebar
The layout that i want to query data: its a sidebar
export default async function Layout({ children, }: { children: React.ReactNode; }) { const queryClient = new QueryClient(); await queryClient.prefetchQuery({ queryKey: ["dms"], queryFn: () => JSON.stringify(client.api.dms.get()), }); return ( <div className="flex w-full"> <HydrationBoundary state={dehydrate(queryClient)}> <ConversationSidebar /> {children} </HydrationBoundary> </div> ); ```
1 Reply
deep-jade
deep-jade9mo ago
I had a similar problem. IIRC either by moving HydrationBoundary before QueryClientProvider or by passing queryClient={queryClient} to HydrationBoundary I was able to fix this issue. HTH

Did you find this page helpful?