ProNextJS
    Loading
    lesson

    The Full Route Cache

    Jack HerringtonJack Herrington

    Note: In order to build the example code you will need to be running the time-api server

    # from 01-next-caching run
    
    cd ./time-api &&
    pnpm install &&
    pnpm dev
    

    Let's explore the full route cache in the Next.js App Router.

    As the name implies, it caches the entire route. We'll work with a basic Next.js application containing a single route. When refreshed, it displays a new time.

    The Example App

    Our application is a standard Next.js setup with shadcn and Tailwind for styling.

    When we load the page, we see the current time displayed. The time updates with each refresh.

    Here's the code for our page component:

    // inside src/app/page.tsx
    export default function Home() {
      console.log(`Rendering / ${new Date().toLocaleTimeString()}`);
      return (
        <main>
          <div>{new Date().toLocaleTimeString()}</div>
        </main>
      );
    }
    

    This code logs the current time to the console and also renders it within a div element.

    When running in development mode, hitting refresh updates the displayed time, generating a new console log entry with each refresh.

    However, things behave differently in production mode.

    After building the app with the next build command and starting it in production mode (next start), refreshing the page consistently displays the same time. This behavior stems from Next.js's ability to recognize and treat this route as static during the build process.

    Static and Dynamic Routes

    Next.js classifies routes as either static or dynamic. Our page, as it stands, is a static route. It doesn't involve elements that would necessitate re-rendering on the server for each request.

    generating static pages during build

    The build process generates static HTML for these routes, resulting in the same content served on each request. Static routes are great for performance, as they eliminate server roundtrips for unchanged content.

    Conversely, dynamic routes require server-side rendering for every request.

    Inspecting the route table generated after building a Next.js application can tell you if a route is static.

    Here is our route table:

    Route table shows / is static

    Notice the "O" next to the / route. This "O" signifies a statically generated route. Static routes are optimal for performance, but there are times when you might want to force a route to render dynamically.

    Forcing Dynamic Rendering

    There are situations where you might want to force a route to render dynamically. Let's look at a couple of ways to achieve this.

    Using unstable_noStore

    One approach is to use the unstable_noStore function from next/cache. By invoking this function within our React server component, we signal to Next.js that the route should be treated as dynamic.

    Here's how we incorporate it:

    // inside app/page.tsx
    
    import { unstable_noStore as noStore } from 'next/cache';
    
    export default function Home() {
      unstable_noStore();
      console.log(`Rendering / ${new Date().toLocaleTimeString()}`);
      ...
    

    After rebuilding and starting the application, we can see that the / route is now marked with an "F", indicating it is a dynamic route:

    the f means we have a dynamic route

    Refreshing the page now generates a new time on each request. The unstable_noStore function effectively prevents Next.js from statically generating the route.

    The route table, generated during the build process, serves as the definitive guide for understanding how Next.js handles caching for your routes.

    Other Ways to Force Dynamic Rendering

    unstable_noStore isn't the only way to indicate that a route is dynamic. Actions within the component that suggest dynamic behavior can also achieve this. For instance, accessing properties of the incoming request can signal to Next.js that the component needs dynamic rendering.

    Can you think of methods to access the incoming request within a React server component?

    We'll look at some in the next lesson.

    Transcript