skip to Main Content

For this question I have created the following demo Next.js application using the App directory:

  1. It has a standard RootLayout in app/layout.tsx.
  2. It has a nested Layout in a route group app/(app)/layout.tsx. This layout contains <nav />.
  3. It has two server-side rendered pages: app/(app)/a/page.tsx and app/(app)/b/page.tsx.
  4. Each page calls getCurrentTime() (defined on app/functions.ts) and then display the render time.

I want each navigation to a page to cause a re-render and run getCurrentTime() again, but I couldn’t make the pages not cache. I’ve tried adding both export const revalidate = 0 and export const dynamic = "force-dynamic" (docs), but couldn’t make it work.

I’m sure it’s pretty basic, but I still couldn’t get the hang of it.

View on StackBlitz

enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    According to the Next.js docs, seems like the mechanism responsible for caching pages on the client is the Router Cache and its purpose is to reduce server requests on navigation (source).

    The documentation says: (source)

    Opting Out ‒ It's not possible to opt out of the Router Cache. However, you can invalidate it by calling router.refresh, revalidatePath, or revalidateTag . This will clear the cache and make a new request to the server, ensuring the latest data is shown.

    Since revalidatePath and revalidateTag can only be used in a server action, I ended with this creating a pseudo client component that will refresh the page on any navigation to it.

    It's not the prettiest solution but it works.

    "use client";
    import { useRouter } from "next/navigation";
    import { useEffect, useRef } from "react";
    
    const Refresh = () => {
      const router = useRouter();
      useEffect(() => {
        const timeout = setTimeout(() => router.refresh(), 0);
        return () => clearTimeout(timeout);
      }, [router]);
      return null;
    };
    
    export default Refresh;
    

  2. I would just move time to a client component

    "use client";
    
    import { getCurrentTime } from "@/app/functions";
    
    export const Time = (): JSX.Element => {
      return <span>{getCurrentTime()}</span>;
    };
    

    Check out related topic How can I disable cache on a specific page only in Next.JS

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search