Static and Dynamic Rendering

In Next.js, a route can be statically or dynamically rendered.

  • In a static route, components are rendered on the server at build time. The result of the work is cached and reused on subsequent requests.
  • In a dynamic route, components are rendered on the server at request time.

Static Rendering (Default)

Static rendering (default) improves performance because all the rendering work is done ahead of time and can be served from a Content Delivery Network (CDN) geographically closer to the user.

You can opt into dynamic rendering by using a dynamic function or dynamic data fetching in a layout or page. This will cause Next.js to render the whole route dynamically, at request time.

This table summarizes how dynamic functions and static data fetching (caching) affect the rendering behavior of a route.

Data FetchingDynamic FunctionsRendering
Not CachedNoDynamic
Not CachedYesDynamic

Note how, for a route to be statically rendered, the data requests are cached and there are no dynamic functions.

Static Data Fetching (Default)

By default, Next.js will cache the result of fetch() requests that do not specifically opt out of caching behavior. This means that fetch requests that do not set a cache option will use the force-cache option.

If any fetch requests in the route use the revalidate option, the route will be re-rendered statically during revalidation.

To learn more about caching data fetching requests, see the Caching and Revalidating page.

Dynamic Rendering

During static rendering, if a dynamic function or a dynamic fetch() request (no caching) is discovered, Next.js will switch to dynamically rendering the whole route at request time. Any cached data requests can still be re-used during dynamic rendering.

Using Dynamic Functions

Dynamic functions rely on information that can only be known at request-time such as a user's cookies or current requests headers. In Next.js, these are: cookies() and headers().

Since the returned value of these functions cannot be known ahead of time, using them in a layout or page will force dynamic rendering at request time.

Using Dynamic Data Fetches

Dynamic data fetches are fetch() requests that specifically opt out of caching behavior by setting the cache option to 'no-store' or revalidate to 0.

The caching options for all fetch requests in a layout or page can also be set using the segment config object.

To learn more about Dynamic Data Fetching, see the Data Fetching page.

Next Steps