One possible pattern for fetching data in a hybrid server-client NextJS app
With NextJS 13 and React 18, we have a new ability to get data server-side via react server components.
Given that, how should we make sure that data is hydrated into our client component fetching patterns?
We can use SWRConfig
(which is using the provider pattern) via the value
prop to pass in fallback
object with our server gotten data. Then any useSWR
nested in that component tree will have access to that fallback data when it tries to fetch data.
To actually make this work we need to make a wrapper SWRProvider
component that will wrap SWRConfig
as it is not useable as is in server components
// SWRProvider.tsx 'use client'; import { SWRConfig } from 'swr'; export const SWRProvider = ({ fallback, children }) => { return <SWRConfig value={{ fallback }}>{children}</SWRConfig>; };
Then we can use it in our server component like so:
// MyServerPage.tsx import { SWRProvider } from './SWRProvider'; export default function MyServerPage() { const { data: user, error } = await fetchUser(); return ( <SWRProvider fallback={{ user }}>{/* your react tree here */}</SWRProvider> ); }
Then in any client component that is nested in that tree, when we use useSWR
to fetch a user, the fallback data will be used instantly until the client-side fetch is complete.
// MyClientComponent.tsx import useSWR from 'swr'; export default function MyClientComponent() { const { data: user, error } = useSWR('user', fetchUser); return ( <div> <h1>{user.name}</h1> <p>{user.bio}</p> </div> ); }