Is any exception that client fetch should be used instead of server fetch? #94701
Replies: 4 comments 2 replies
-
|
There'll eventually be an API to kind of do this, but often the roundtrip to the server still preserves client state and can be done in such a way that the result ends up streaming while the rest of the UI is resolved/rendered quickly. |
Beta Was this translation helpful? Give feedback.
-
|
Great question. The short answer is: Client-side data fetching is still valid in App Router, but for different use cases than Pages Router. Pages Router (Old): Client fetch was recommended for: · Authenticated content (user-specific dashboards) App Router (New): When to use Server Fetch (default): · Public content (can be cached & shared) When to use Client Fetch (with useEffect or useSWR/react-query): · Real-time dashboards (stock prices, live data) Your Specific Concern: "Server fetch re-renders entire tree" → Yes, but Next.js 14+ is optimized. For most apps, it's fine. "Client cache invalidation after server action" → Here's the pattern: // Server Action
'use server'
async function updateData(formData: FormData) {
// update database
revalidatePath('/dashboard') // revalidates server cache
}
// Client component with SWR
const { data, mutate } = useSWR('/api/data', fetcher)
// After server action success
mutate() // instantly refreshes client cacheBottom line: Both approaches still valid. Use server fetch by default. Use client fetch + SWR/React Query when:
The article is conceptually still valid, just the tools have evolved. |
Beta Was this translation helpful? Give feedback.
-
|
hort version: there's no hard "use client fetch instead of server fetch" Reach for client-side fetch when:
For everything else — public content, SEO-relevant pages, anything cacheable Now to the two things you're actually running into, because thats where the 1. "Server fetch re-renders the whole tree when I change a URL param" It feels that way, but it isn't the whole tree. Updating
So you get fresh server data without shipping the fetch to the client — the 2. "Client fetch + server action = cache invalidation hell" Two clean patterns:
The thing that causes the "hell" is mixing the two: server-fetching the data TL;DR: default to server fetch; use client fetch for browser-state, |
Beta Was this translation helpful? Give feedback.
-
|
The roundtrip isn't what you're optimizing away. What differs between client and server fetch is what re-renders and who owns the cache, not whether a network call happens. So the choice is about ownership and invalidation, not latency-elimination. A deep tree of cheap server components costs nothing to re-render. The cost is where you Isolate the await behind a Suspense boundary as low as possible. See, https://nextjs.org/docs/app/guides/streaming#push-dynamic-access-down. There's a couple choices to make here:
Changing the key remounts the boundary. It's a fresh mount with no "already-revealed content". The the fallback shows on every Wrap the navigation in a transition React's rule: it will not hide already-revealed content with a fallback during a transition. So if the table is already on screen and the transition causes the server component to suspend, React keeps the old table visible and just flips Pick one:
All of these are still "server fetch + roundtrip", they're just about hiding the roundtrip well. Client fetch (SWR/React Query) remains the escape hatch when the data is browser-state/real-time/interaction-gated, at the cost of owning the cache. And a side note, a Client Component can be parent (not rendering owner) of a Server component: https://nextjs.org/docs/app/getting-started/server-and-client-components#interleaving-server-and-client-components As said before, there'll likely be an API to do what you are thinking about, in the short/medium term future, but for now, the above applies. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Related to the old Pages router I found an article explaining when it's recommended to use client fetch: https://nextjs.org/docs/pages/building-your-application/data-fetching/client-side. I would like to know if this is still valid for App Router.
The main issue is that server fetch requires the URL to be manipulated (pushing params to the URL) so that the server knows what data to fetch, but this triggers a server-side component re-render and re-renders the entire tree again.
However, doing the fetch on the client brings another question about the cache invalidation because if we use a server action to update this data, we'll need to do a workaround to manually invalidate the client cache.
Beta Was this translation helpful? Give feedback.
All reactions