Suspense fallback shows empty screen before data when using prefetch in Server Components
Provide environment information
System:
OS: Windows 11
CPU: (8) x64
Memory: 16 GB
Shell: PowerShell
Binaries:
Node: 20.11.1
pnpm: 8.15.4
Browsers:
Chrome: 122.0.6261.112
npmPackages:
typescript: 5.4.5
next: 14.2.3
react: 18.3.1
react-dom: 18.3.1
@trpc/server: 11.0.0-rc.467
@trpc/client: 11.0.0-rc.467
@trpc/react-query: 11.0.0-rc.467
@trpc/next: 11.0.0-rc.467
@tanstack/react-query: 5.40.0
@tanstack/react-query-devtools: 5.40.0
Describe the bug
When using prefetch in a Server Component with Suspense, the component shows the Suspense fallback first, then briefly shows an empty screen before finally displaying the data. This creates a jarring user experience with multiple visual states.
Following the [official documentation for Leveraging Suspense](https://trpc.io/docs/client/react/server-components#leveraging-suspense), but experiencing undesired loading states.
when I refresh the page it shows suspense fallback (skeleton) => empty screen => data
Link to reproduction
none
To reproduce
Server Component (app/gallery/photos/[id]/page.tsx):
export default function PhotoPage({ params }: { params: { id: string } }) {
const photoId = params.id;
void trpc.photos.getPhotoById.prefetch(photoId);
return (
<HydrateClient>
<Suspense fallback={<PhotoDetailSkeleton />}>
<PhotoDetail id={params.id} isModal={false} />
</Suspense>
</HydrateClient>
);
}
Client Component Hook:
export function useGetPhotoById(id: string) {
return trpc.photos.getPhotoById.useSuspenseQuery(id, {
staleTime: 1000 * 60 * 5,
gcTime: 1000 * 60 * 30,
refetchOnMount: false,
refetchOnWindowFocus: false,
});
}
Additional information
Expected Behavior
The component should transition smoothly from Suspense fallback directly to the data without showing an empty screen in between.
Actual Behavior
The loading sequence is:
- Suspense fallback (skeleton)
- Empty screen
- Actual data
Additional Information
- Using Next.js App Router
- Following RSC patterns from tRPC documentation
- Issue occurs consistently on initial load
- Using latest tRPC RC version (11.0.0-rc.467)
- Using latest React Query version (5.40.0)
Would appreciate guidance on how to achieve a smooth transition from skeleton to data without the empty screen flash.
๐จโ๐งโ๐ฆ Contributing
- [X] ๐โโ๏ธ Yes, I'd be down to file a PR fixing this bug!