Server component rerender full page after revalidate tag #66228
Replies: 17 comments 6 replies
-
If I have a server component RSC Parent (entry point As a solution, I've currently decided to move the UI update from cache revalidation to CSR, but maybe I'm missing something and there's a way to revalidate a specific child without refreshing the entire page? Refreshing the whole page is not suitable because there is a socket connection, and reconnecting due to an update of a component unrelated to the socket is unnecessary. Is it normal for the revalidation of a tag in a child to trigger the re-streaming of the entire page? In my understanding, revalidating a field in the Data Cache by a specific tag should provide me with on-demand rebuilding of the necessary server component, its subsequent streaming, and mounting using React and the RSC payload instructions that come after revalidation. I tried various compositions, removed unnecessary props being passed from the RSC Parent to the RSC Child, disabling some application functionality as an experiment. I tried wrapping the RSC Child in https://codesandbox.io/p/devbox/eager-proskuriakova-forked-3v5nwp In this example, we have the main entry point page, RSC Parent. Within its tree, there's RSC Child, which fetches a dummy API with movies and displays their titles, with the fetch using the tag: "movies". There are two buttons: one for revalidating the "movies" tag and another for triggering a refresh, which according to the documentation should work as follows: "Refresh the current route. Making a new request to the server, re-fetching data requests, and re-rendering Server Components. The client will merge the updated React Server Component payload without losing unaffected client-side React (e.g. useState) or browser state (e.g. scroll position)." Instead of a real socket, there's a client component with an effect: it logs "connect" when mounted and "disconnect" when unmounted. Both tag revalidation and route refresh will remount the client component.
|
Beta Was this translation helpful? Give feedback.
-
I also tried to pass In addition to that, I tried specifying an immutable key for |
Beta Was this translation helpful? Give feedback.
-
I also tried putting |
Beta Was this translation helpful? Give feedback.
-
I did a bit of researching of the Next.js source code, deployed it locally, and added a project from the examples provided above (thanks to the Next.js developers for making a clear guide on how to set it all up). I searched for references related to revalidation for the entry point since the monorepository is HUGE. I set a breakpoint, navigated through the call stack, found the approximate place where the component tree for the entire page is generated, and started reading the code. Research:
Okay, interesting that I have client-side navigation during tag revalidation. I conclude that this is purely a limitation of the current implementation of Next.js's app-render. By the way, I tried passing |
Beta Was this translation helpful? Give feedback.
-
still no answer |
Beta Was this translation helpful? Give feedback.
-
I stumbled upon this discussion after noticing this behavior too. I spent a moment with the react profiler trying to figure out why things re-rendered from the router down after a flag revalidation, no idea why next does this. |
Beta Was this translation helpful? Give feedback.
-
Maybe there is the answer: https://nextjs.org/docs/app/building-your-application/caching#invalidation-1
|
Beta Was this translation helpful? Give feedback.
-
This is a serious issue for me since we use a modal for update, when invalidate tag, the page is refreshed, and close my modal |
Beta Was this translation helpful? Give feedback.
-
Also facing this issue. |
Beta Was this translation helpful? Give feedback.
-
Dan Abramov apparently also went through the wrong door (reference to Kirkorov) |
Beta Was this translation helpful? Give feedback.
-
I'm also facing this problem. In the root layout, my code is wrapped in a context where i have a userCtx that is used everywhere in my app. The solution should be to fetch the user by tag on each page , by passing the userCtx from the context but that's mean I have to propagate the user props every where i need it. Second solution should be to use React Query .... |
Beta Was this translation helpful? Give feedback.
-
When you revalidate a cache tag in a child server component, the entire page gets rebuilt and sent back to the client. This happens because Next.js ties cache invalidation to the route level, so any revalidation within a route triggers the regeneration of the whole tree associated with that route, starting from the entry point. Server components don't yet support updating just a specific part of the tree; they work with the entire route as a unit. Wrapping the child in Suspense doesn’t help because the issue lies in how Next.js handles revalidation at the route level. Server-side updates lack the granularity needed to target just the child component, which is why the full page gets refreshed. For now, managing updates on the client side is the best approach. It allows for finer control and avoids disrupting unrelated parts of your application. As Next.js evolves, we might see better support for targeted updates in server components. |
Beta Was this translation helpful? Give feedback.
-
Also facing the same issue. |
Beta Was this translation helpful? Give feedback.
-
same issue here, on server function tag revalidation i get other server components in the same page revalidated as well. |
Beta Was this translation helpful? Give feedback.
-
I encountered a full-page reload issue when using revalidateTag() in my Next.js App Router. 🔹 Setup:
where Search.jsx is wrapped in memo(Search). 🔴 Problem:
🔍 Why This Happens:
When memo(Search) is used:
🚀 Solution: Avoid memoizing layout components that depend on revalidateTag() updates. |
Beta Was this translation helpful? Give feedback.
-
Fixed by creating using src/app/api/revalidate/route.ts import { revalidateTag } from "next/cache";
import { NextResponse } from "next/server";
export async function POST(req: Request) {
try {
const { tags } = await req.json();
if (!tags || !Array.isArray(tags)) {
return NextResponse.json({ error: "Invalid tags format" }, { status: 400 });
}
tags.forEach((tag) => revalidateTag(tag));
return NextResponse.json({ success: true });
} catch (error) {
return NextResponse.json({ error: "Failed to revalidate" }, { status: 500 });
} then calling it using fetch const revalidateTags = async () => {
fetch(`/api/revalidate`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
tags: [`tag`, `another_tag`],
}),
});
}; |
Beta Was this translation helpful? Give feedback.
-
I just ran into this odd functionality. I have a modal open and when a user changes a setting, we persist the setting to the db and revalidate a tag. The tag is not used on this current page -- it's used on completely unrelated fetches. The The workaround solution for me was to not use a server action to perform the This appears to revalidate successfully and does not close the modal. |
Beta Was this translation helpful? Give feedback.
-
Summary
This is example how on refresh rerender in react dev tools whole page
https://codesandbox.io/p/devbox/eager-proskuriakova-mq2pyk
I expect will rerender only List in Suspense with fallback loading
Additional information
No response
Example
No response
Beta Was this translation helpful? Give feedback.
All reactions