Static, cached, dynamic
Prerender the shell, cache shared data, stream runtime data.
Next.js docsGetting started · Cache Components
Cache Components enable Partial Prerendering (PPR) - mix static, cached, and dynamic content in a single route.
From next-cache-components, “Three Content Types”.
Build it, then request it
Pick a boundary per block, then press Request.
app/dashboard/page.tsxBuilds
BrowserServer clock
/dashboard
Waiting for the server…
static
DashboardOverviewReportsSettings
cached
Revenue$48.2k
Orders312
As of09:00
Prerendered into the shell
dynamic
Streams in per request
- Shell painted
- –
- Stats
- –
- Notifications
- –
Which of the three is it?
Pick a snippet or type your own.
static
Static shell
Cached
Dynamic hole
Fix first
// Static: sync markup, prerendered at build
<header><h1>Our Blog</h1></header>
// Cached: async, shared across requests
async function BlogPosts() {
'use cache'
cacheLife('hours')
const posts = await db.posts.findMany()
return <PostList posts={posts} />
}
// Dynamic: runtime data, behind a boundary
<Suspense fallback={<p>Loading...</p>}>
<UserPreferences /> {/* (await cookies()).get('theme') */}
</Suspense>
Migrate old route config
Press Try on a row, or paste your own config.
| Old | With Cache Components | Load |
|---|
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
cacheComponents: true,
}
export default nextConfig
Why it matters, pros and cons
Why it matters
Each part takes its cheapest strategy, so the shell never waits on a slow query.
Pros
- First paint comes from the prerendered shell.
- Cached parts skip the database.
- Missing boundaries fail the build, not users.
Cons
- No Edge runtime or static export.
cookies()can’t run inside'use cache'.- Too many holes reads as a skeleton page.