Here's where we're headed with caching in Next.js.
Last month, we shipped a release candidate for v15, which starts to address some of the community feedback on caching. tl;dr many parts are no longer cached by default.
In Next.js 15, if I make a fetch to some API, or make a database query, the result is not cached. This is something dynamic. If you want to cache the data, you can opt-in to this behavior. You need to be explicit.
I've seen a few questions floating around that I'd like to clarify 😁
What is prerendering?
Prerendering is where we try to generate a static HTML page during `next build`. This is separate from caching data fetching or database queries.
Today, there's "all of nothing" prerendering. Either your entire page is static, or it's dynamic from using a function that reads the incoming request. Ideally, we could have both together: send the static parts of the page to all users, while streaming the dynamic parts that are unique to the user.
Why is local development different than production?
When you're running your local dev server, and you reload the page, your components fetch new data—the results are not cached. You expect to see fresh data. In production, you might want to prerender the entire page to HTML and serve the same rendered page to all users.
When you create a production build, Next.js tries to prerender the application routes (since Next.js 9). In the Pages Router, this happens automatically when you don't use `getServerSideProps`. You can do additional data fetching for a static route using `getStaticProps`. Using `getServerSideProps` will opt you into dynamically rendering the route.
In the App Router, and with Server Components, you can fetch data from components. But just because I'm fetching data, doesn't always mean I want that component to be dynamically rendered. Some of my Server Components should be able to be prerendered to static HTML.
This isn't as explicit as the Pages Router APIs. Your page only becomes dynamically rendered when you read something from the incoming request. For example, reading `searchParams`, `cookies`, or `headers`. Doing a `fetch` does not automatically make the page dynamic today, because you might want that component to be prerendered.
Why not prerender in local development?
We believe the local dev experience should be as "lazy" as possible. Pages should compile on demand; you wouldn't want to wait for every single route to compile before you can get started.
Prerendering every route on save would be slow, which goes against our ambition to keep improving Fast Refresh times. With Fast Refresh, you can make a change to your code, hit save, and see the application update near instantly without losing your current client state.
I understand the desire to know whether the page will be prerendered or not during local dev, though. We used to show an icon in the bottom right of the screen, if the page would get prerendered. We're bringing this back!
Where are we headed with Next.js?
With the v15 stable release, we'll be writing more in the blog about our plans for the future. Our goal is to make all async operations (like doing a `fetch`) opt into dynamic rendering, similar to how using `headers` opts into dynamic rendering.
We believe Partial Prerendering will become the default way of building Next.js applications. In this world, routes can be both static and dynamic.
Even if the majority of your application is dynamic, you can still have a "shell" of your application that gets sent to the browser immediately, and then have the rest of your page (the dynamic parts) stream in parallel. This shell could even only be the link preload headers, for example.
If you want more of the route to be included in the prerender, you can wrap the dynamic parts of your page in React Suspense to define a fallback state. Next.js can then prerender up to that Suspense boundary as part of the build process. When serving the page, the user is immediately shown the prerendered HTML while simultaneously streaming the dynamic parts of the route.
Partial Prerendering is fully supported with `next start` (the production Next.js server) and is experimental today.
When can I try this out?
Next.js v15 stable will be released soon, which includes the previously mentioned default caching changes. Either in v15.0.0 or in a minor version soon after, we'll allow you to try the vision above for where we're headed behind an opt-in flag.
We're taking time to validate these early features with our own applications, some early partner customers, and the community to ensure they're well tested in large Next.js applications.
We're also working on simplifying the existing caching APIs and building DevTools for Next.js, which we feel are important pieces for completing the vision. More on this soon!
In conclusion, with Next.js 15:
• `fetch` requests are no longer cached by default
• Route Handlers are no longer cached by default
• Client-side navigations will no longer keep a cached version of the last page for 30 seconds when using `` or `useRouter`
We'll also make it easy to keep the existing behavior, if you prefer, in the upgrade guide. Okay, that's all for now!
• • •
Missing some Tweet in this thread? You can try to
force a refresh
You have a `Request` – how do you get the visitor geolocation?
Just wrote new docs for @nextjs and wanted to share some of the interesting bits ↓
The `headers()` function allows you to read from the incoming request. For example, here we're pulling `x-forwarded-for` (or `x-real-ip`) in a function.
The `getIp` function can then be used in any Server Component. But we want the location, not the raw IP!
P.S. in the future with Partial Prerendering, you can use Suspense to wrap the dynamic component, allowing the rest of the page to still be prerendered.