Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Cache Components and use cache

Cache Components is a new caching model introduced in Next.js 16. You turn it on with a setting, and it changes the approach: all data is dynamic by default, and you explicitly mark what may be stored with the 'use cache' directive. A page is then assembled from a static "shell" prepared in advance and dynamic parts that stream in. This approach is called Partial Prerendering.

Turning it on

Add the setting to next.config.ts and restart the development server:

// next.config.ts
import type { NextConfig } from 'next';
 
const nextConfig: NextConfig = {
  cacheComponents: true,
};
 
export default nextConfig;

Without this setting the 'use cache' directive and the functions in this lesson do not work.

Caching a data function

The 'use cache' directive at the start of an async function stores its result. Let us do that with the posts list:

// lib/posts.ts (fragment)
import { cacheLife, cacheTag } from 'next/cache';
 
export async function getPosts(): Promise<Post[]> {
  'use cache';
  cacheLife('hours');
  cacheTag('posts');
 
  return db.select().from(posts);
}

cacheLife('hours') sets the lifetime — about an hour, cacheTag('posts') gives the result a tag. Function arguments are part of the cache key: getPost('a') and getPost('b') are stored separately. The home page and /posts now show the list from the cache.

cacheLife profiles

ProfileWhat for
'seconds'Data that changes constantly
'minutes'Frequent updates
'hours'Several updates a day
'days'A daily update
'weeks'A weekly update
'max'Data that almost never changes

Clearing after adding a post

In the createPost server action, after writing to the database, call updateTag('posts') from next/cache — the cache with that tag is dropped, and the new post shows up in the list immediately.

Uncached data goes into Suspense

Data without 'use cache' and reads of cookies() or headers() run on every request. Such a component must be wrapped in Suspense — like Comments in the streaming lesson:

// app/posts/[slug]/page.tsx (fragment)
<Suspense fallback={<p>Loading comments...</p>}>
  <Comments />
</Suspense>

The placeholder goes into the static shell, and the comments stream in. If you forget Suspense, the development server shows a hint about a blocking route.

What changes in the project

  • The dynamic, revalidate and fetchCache exports from pages are no longer needed and cause an error — 'use cache', cacheLife and Suspense replace them.
  • dynamicParams is not supported, and generateStaticParams must return at least one item.
  • The build table shows the ◐ symbol — a page with a prebuilt shell and streamed parts.

The course is built on the regular model, because a new project is created without this setting. Turn on Cache Components deliberately, when you are ready to go through every page.

Common mistake

Calling cookies() inside a function with 'use cache'. The cache is shared by all visitors, so request data is not allowed inside it — Next.js throws an error. Read the cookie outside, in an uncached component, and pass the value into the cached function as an argument.

Thanks for reading!

Donate to the site — we work hard for you.