T
TanStack6mo ago
jolly-crimson

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
like-gold
like-gold6mo ago
So the getAuthSessions is it predefined by default
deep-jade
deep-jade6mo 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...
jolly-crimson
jolly-crimsonOP6mo ago
I placed the cache according to the example
No description
jolly-crimson
jolly-crimsonOP6mo ago
But it keeps making two requests
No description
deep-jade
deep-jade6mo ago
@Ephem can help maybe?
mute-gold
mute-gold5mo 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?