Disable next.js 13 cache for server component (no fetch)

920 views Asked by At

I am trying to redirect user to other pages based on their logged in status.

I ran into a issue, When I first call getSession, it is getting cached somehow.

getSession

const getSession = async (): Promise<TSession> => {
  const token = cookies().get("token");
  if (!token) return null;
  const secret = new TextEncoder().encode(process.env.JWT_SECRET!);
  const result = await jwtVerify(token.value, secret);
  const sub = result.payload.sub;
  // NOTE: Verify token in database
  if (!sub) return null;
  const user = await prisma.user.findFirst({ where: { id: sub } });
  if (!user) return null;
  return { user };
};

So, if user is logged out, the initial session is null. And after signing in user is redirected to /dashboard

SignIn Handler

const onValid = async (data: SignInSchemaType) => {
    try {
      const user = await mutateAsync(data);
      toast.success("Login successful");
      dispatch({ type: "login_success", payload: user });
      const callback = searchParams.get("callback") || "/dashboard";
      router.push(callback);
    } catch (e) {
      if (e instanceof TRPCClientError)
        setError("root", { message: e.message });
    }
  };

I made sure that the cookies are updated and well yes they are. When I navigate to / (index) back, it doesn't redirect me to /dashboard anymore. But once I refresh the page the session get's updated and it works.

Same happens other way around, when user logout, He redirect's back to /sign-in but when he navigate to /dashboard it works, now the session is again cached (which is not null this time)

Here is how I handled redirection

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const session = await getSession();
  console.log(session);
  if (session?.user) redirect("/dashboard/links");
  // rest of code
}

P.S. The above layout component is not global layout, it is only assigned to / & /sign-in

2

There are 2 answers

0
WiperR On BEST ANSWER

In Next.js, layouts do not re-render when the page changes. To solve this problem, I moved the authentication check to specific pages. However, I still needed server-side authentication checks. I validated tokens and JWT signatures in middleware.

Please note that you cannot perform database operations in middleware because it runs on the edge. More information about the edge runtime can be found in the Next.js documentation.

P.S. Many DB drivers started to support edge runtime, you may still have to research.

1
Sammeeey On

I think I solved a similar issue following this advice here.

  1. stop server
  2. delete /.next in root directory
  3. restart server

You can also opt out of this caching in each fetch request.

But I wonder if there's a way to stop this caching behavior project-wide.