T
TanStack3mo ago
sensitive-blue

Experimental streaming without prefetching in Next.js

I am using @tanstack/react-query-next-experimental and I understand that a new QueryClient is created for each server request. However, on a single frontend route, I have both the layout and the page, which are server-side, and they make the same request to the backend. Is there any alternative where I can cache these requests within the same frontend route? layout.tsx:
import { getAuthSessionOptions } from '@/http/openapi/@tanstack/react-query.gen'
import { getQueryClient } from '@/lib/query'
import { redirect } from 'next/navigation'

export const dynamic = 'force-dynamic'

interface LayoutProps {
children: React.ReactNode
}

export default async function Layout({ children }: LayoutProps) {
const queryClient = getQueryClient()

const session = await queryClient.fetchQuery({
...getAuthSessionOptions(),
})

if (!session?.user) redirect('/api/auth/signout')

return children
}
import { getAuthSessionOptions } from '@/http/openapi/@tanstack/react-query.gen'
import { getQueryClient } from '@/lib/query'
import { redirect } from 'next/navigation'

export const dynamic = 'force-dynamic'

interface LayoutProps {
children: React.ReactNode
}

export default async function Layout({ children }: LayoutProps) {
const queryClient = getQueryClient()

const session = await queryClient.fetchQuery({
...getAuthSessionOptions(),
})

if (!session?.user) redirect('/api/auth/signout')

return children
}
page.tsx:
import { getAuthSessionOptions } from '@/http/openapi/@tanstack/react-query.gen'
import { getQueryClient } from '@/lib/query'
import { getAbilityServer } from '@/lib/server'
import { redirect } from 'next/navigation'

export default async function Page() {
const queryClient = getQueryClient()

const session = await queryClient.fetchQuery({
...getAuthSessionOptions(),
})

const { can } = await getAbilityServer(session)
const canGetUser = can('get', 'User')
if (!canGetUser) redirect('/dashboard')

return <h1>example</h1>
}
import { getAuthSessionOptions } from '@/http/openapi/@tanstack/react-query.gen'
import { getQueryClient } from '@/lib/query'
import { getAbilityServer } from '@/lib/server'
import { redirect } from 'next/navigation'

export default async function Page() {
const queryClient = getQueryClient()

const session = await queryClient.fetchQuery({
...getAuthSessionOptions(),
})

const { can } = await getAbilityServer(session)
const canGetUser = can('get', 'User')
if (!canGetUser) redirect('/dashboard')

return <h1>example</h1>
}
@julius I believe you are one of the few who have the knowledge to assist me
No description
6 Replies
conscious-sapphire
conscious-sapphire3mo ago
So the getAuthSessions is it predefined by default
harsh-harlequin
harsh-harlequin2mo ago
Advanced Server Rendering | TanStack Query React Docs
Welcome to the Advanced Server Rendering guide, where you will learn all about using React Query with streaming, Server Components and the Next.js app router. You might want to read the before this on...
sensitive-blue
sensitive-blueOP2mo ago
I placed the cache according to the example
No description
sensitive-blue
sensitive-blueOP2mo ago
But it keeps making two requests
No description
harsh-harlequin
harsh-harlequin2mo ago
@Ephem can help maybe?
fascinating-indigo
fascinating-indigo2mo ago
Hey! I'm currently on vacation and have been/am still a bit off grid so haven't been able to look at this until now. What's happening might be that you are both prefetching in server components AND using the experimental package to fetch during render. The queryClient in the SC environment is different from the one used during the Server Side Rendering pass, and the fetch deduplication also works per environment I believe, so that's why mutliple requests are being made, one being from somewhere in children? Try adding a <HydrationBoundary state={dehydrate(queryClient)}> wrapper around the children in layout and page and see if that fixes it?

Did you find this page helpful?