# Next Cache Components > Next.js 16 Cache Components guidance — PPR, use cache directive, cacheLife, cacheTag, updateTag, and migration from unstable_cache. Use when implementing partial prerendering, caching strategies, or migrating from older Next.js cache patterns. Fuente: https://skillsagentes.com/skills/vercel/vercel-plugin/next-cache-components Markdown: https://skillsagentes.com/skills/vercel/vercel-plugin/next-cache-components.md Repositorio: https://github.com/vercel/vercel-plugin Autor: vercel Licencia: NOASSERTION Actualizado: hace 5 meses Coste de contexto: 61 tok instalada, 2.9k tok al activarse, 5.9k tok con todos los archivos del bundle Bundle: 3 archivos, 23 KB Permisos que pide: ninguno declarado ## Instalación Un skill son archivos markdown: los mismos archivos valen para cualquier agente y lo único que cambia es el directorio de destino, es decir la bandera `--agent`. Añade `-g` para instalarlo en todos los proyectos de la máquina. ```bash # Claude Code npx -y skills add vercel/vercel-plugin --skill next-cache-components --agent claude-code # Cursor npx -y skills add vercel/vercel-plugin --skill next-cache-components --agent cursor # Codex npx -y skills add vercel/vercel-plugin --skill next-cache-components --agent codex # Gemini CLI npx -y skills add vercel/vercel-plugin --skill next-cache-components --agent gemini # Windsurf npx -y skills add vercel/vercel-plugin --skill next-cache-components --agent windsurf # Cline npx -y skills add vercel/vercel-plugin --skill next-cache-components --agent cline ``` ## Archivos - SKILL.md — 11 KB - overlay.yaml — 2 KB - upstream/SKILL.md — 9 KB ## SKILL.md Reproducido tal cual desde vercel/vercel-plugin bajo NOASSERTION. Esta sección es el documento original y está en inglés. # Cache Components (Next.js 16+) Cache Components enable Partial Prerendering (PPR) - mix static, cached, and dynamic content in a single route. ## Enable Cache Components ```ts // next.config.ts import type { NextConfig } from 'next' const nextConfig: NextConfig = { cacheComponents: true, } export default nextConfig ``` This replaces the old `experimental.ppr` flag. --- ## Three Content Types With Cache Components enabled, content falls into three categories: ### 1. Static (Auto-Prerendered) Synchronous code, imports, pure computations - prerendered at build time: ```tsx export default function Page() { return (

Our Blog

{/* Static - instant */}
) } ``` ### 2. Cached (`use cache`) Async data that doesn't need fresh fetches every request: ```tsx async function BlogPosts() { 'use cache' cacheLife('hours') const posts = await db.posts.findMany() return } ``` ### 3. Dynamic (Suspense) Runtime data that must be fresh - wrap in Suspense: ```tsx import { Suspense } from 'react' export default function Page() { return ( <> {/* Cached */} Loading...

}> {/* Dynamic - streams in */}
) } async function UserPreferences() { const theme = (await cookies()).get('theme')?.value return

Theme: {theme}

} ``` --- ## `use cache` Directive ### File Level ```tsx 'use cache' export default async function Page() { // Entire page is cached const data = await fetchData() return
{data}
} ``` ### Component Level ```tsx export async function CachedComponent() { 'use cache' const data = await fetchData() return
{data}
} ``` ### Function Level ```tsx export async function getData() { 'use cache' return db.query('SELECT * FROM posts') } ``` --- ## Cache Profiles ### Built-in Profiles ```tsx 'use cache' // Default: 5m stale, 15m revalidate ``` ```tsx 'use cache: remote' // Platform-provided cache (Redis, KV) ``` ```tsx 'use cache: private' // For compliance, allows runtime APIs ``` ### `cacheLife()` - Custom Lifetime ```tsx import { cacheLife } from 'next/cache' async function getData() { 'use cache' cacheLife('hours') // Built-in profile return fetch('/api/data') } ``` Built-in profiles: `'default'`, `'minutes'`, `'hours'`, `'days'`, `'weeks'`, `'max'` ### Inline Configuration ```tsx async function getData() { 'use cache' cacheLife({ stale: 3600, // 1 hour - serve stale while revalidating revalidate: 7200, // 2 hours - background revalidation interval expire: 86400, // 1 day - hard expiration }) return fetch('/api/data') } ``` --- ## Cache Invalidation ### `cacheTag()` - Tag Cached Content ```tsx import { cacheTag } from 'next/cache' async function getProducts() { 'use cache' cacheTag('products') return db.products.findMany() } async function getProduct(id: string) { 'use cache' cacheTag('products', `product-${id}`) return db.products.findUnique({ where: { id } }) } ``` ### `updateTag()` - Immediate Invalidation Use when you need the cache refreshed within the same request: ```tsx 'use server' import { updateTag } from 'next/cache' export async function updateProduct(id: string, data: FormData) { await db.products.update({ where: { id }, data }) updateTag(`product-${id}`) // Immediate - same request sees fresh data } ``` ### `revalidateTag()` - Background Revalidation Use for stale-while-revalidate behavior: ```tsx 'use server' import { revalidateTag } from 'next/cache' export async function createPost(data: FormData) { await db.posts.create({ data }) revalidateTag('posts') // Background - next request sees fresh data } ``` --- ## Runtime Data Constraint **Cannot** access `cookies()`, `headers()`, or `searchParams` inside `use cache`. ### Solution: Pass as Arguments ```tsx // Wrong - runtime API inside use cache async function CachedProfile() { 'use cache' const session = (await cookies()).get('session')?.value // Error! return
{session}
} // Correct - extract outside, pass as argument async function ProfilePage() { const session = (await cookies()).get('session')?.value return } async function CachedProfile({ sessionId }: { sessionId: string }) { 'use cache' // sessionId becomes part of cache key automatically const data = await fetchUserData(sessionId) return
{data.name}
} ``` ### Exception: `use cache: private` For compliance requirements when you can't refactor: ```tsx async function getData() { 'use cache: private' const session = (await cookies()).get('session')?.value // Allowed return fetchData(session) } ``` --- ## Cache Key Generation Cache keys are automatic based on: - **Build ID** - invalidates all caches on deploy - **Function ID** - hash of function location - **Serializable arguments** - props become part of key - **Closure variables** - outer scope values included ```tsx async function Component({ userId }: { userId: string }) { const getData = async (filter: string) => { 'use cache' // Cache key = userId (closure) + filter (argument) return fetch(`/api/users/${userId}?filter=${filter}`) } return getData('active') } ``` --- ## Complete Example ```tsx import { Suspense } from 'react' import { cookies } from 'next/headers' import { cacheLife, cacheTag } from 'next/cache' export default function DashboardPage() { return ( <> {/* Static shell - instant from CDN */}

Dashboard

{/* Cached - fast, revalidates hourly */} {/* Dynamic - streams in with fresh data */} }> ) } async function Stats() { 'use cache' cacheLife('hours') cacheTag('dashboard-stats') const stats = await db.stats.aggregate() return } async function Notifications() { const userId = (await cookies()).get('userId')?.value const notifications = await db.notifications.findMany({ where: { userId, read: false } }) return } ``` --- ## Migration from Previous Versions | Old Config | Replacement | |-----------|-------------| | `experimental.ppr` | `cacheComponents: true` | | `dynamic = 'force-dynamic'` | Remove (default behavior) | | `dynamic = 'force-static'` | `'use cache'` + `cacheLife('max')` | | `revalidate = N` | `cacheLife({ revalidate: N })` | | `unstable_cache()` | `'use cache'` directive | ### Migrating `unstable_cache` to `use cache` `unstable_cache` has been replaced by the `use cache` directive in Next.js 16. When `cacheComponents` is enabled, convert `unstable_cache` calls to `use cache` functions: **Before (`unstable_cache`):** ```tsx import { unstable_cache } from 'next/cache' const getCachedUser = unstable_cache( async (id) => getUser(id), ['my-app-user'], { tags: ['users'], revalidate: 60, } ) export default async function Page({ params }: { params: Promise<{ id: string }> }) { const { id } = await params const user = await getCachedUser(id) return
{user.name}
} ``` **After (`use cache`):** ```tsx import { cacheLife, cacheTag } from 'next/cache' async function getCachedUser(id: string) { 'use cache' cacheTag('users') cacheLife({ revalidate: 60 }) return getUser(id) } export default async function Page({ params }: { params: Promise<{ id: string }> }) { const { id } = await params const user = await getCachedUser(id) return
{user.name}
} ``` Key differences: - **No manual cache keys** - `use cache` generates keys automatically from function arguments and closures. The `keyParts` array from `unstable_cache` is no longer needed. - **Tags** - Replace `options.tags` with `cacheTag()` calls inside the function. - **Revalidation** - Replace `options.revalidate` with `cacheLife({ revalidate: N })` or a built-in profile like `cacheLife('minutes')`. - **Dynamic data** - `unstable_cache` did not support `cookies()` or `headers()` inside the callback. The same restriction applies to `use cache`, but you can use `'use cache: private'` if needed. --- ## Limitations - **Edge runtime not supported** - requires Node.js - **Static export not supported** - needs server - **Non-deterministic values** (`Math.random()`, `Date.now()`) execute once at build time inside `use cache` For request-time randomness outside cache: ```tsx import { connection } from 'next/server' async function DynamicContent() { await connection() // Defer to request time const id = crypto.randomUUID() // Different per request return
{id}
} ``` Sources: - [Cache Components Guide](https://nextjs.org/docs/app/getting-started/cache-components) - [use cache Directive](https://nextjs.org/docs/app/api-reference/directives/use-cache) - [unstable_cache (legacy)](https://nextjs.org/docs/app/api-reference/functions/unstable_cache) ## Dónde encaja - Categoría: [Bases de datos](https://skillsagentes.com/categorias/bases-de-datos.md) — Diseño de esquemas, migraciones y optimización de consultas. - Creador: [vercel](https://skillsagentes.com/creators/vercel.md) — 79 skills en el directorio - [Todas las skills](https://skillsagentes.com/skills.md) - [Ranking de instalaciones](https://skillsagentes.com/ranking.md) ## Otras skills del mismo repositorio - [Knowledge Update](https://skillsagentes.com/skills/vercel/vercel-plugin/knowledge-update.md): Corrects outdated LLM knowledge about the Vercel platform and introduces new products. Injected at session start. - [Vercel Connect](https://skillsagentes.com/skills/vercel/vercel-plugin/vercel-connect.md): Vercel Connect expert guidance — securely obtain scoped OAuth tokens for third-party services (Slack, GitHub, MCP servers, OAuth, Snowflake) on behalf of apps or users via Vercel OIDC. Use when wiring up third-party API access, connecting to MCP servers, sending Slack messages, accessing GitHub APIs, receiving webhook events from Slack/Linear/GitHub and forwarding them to your agents and apps, or building eve agent connections. - [Vercel Functions](https://skillsagentes.com/skills/vercel/vercel-plugin/vercel-functions.md): Vercel Functions expert guidance — Serverless Functions, Edge Functions, Fluid Compute, streaming, Cron Jobs, and runtime configuration. Use when configuring, debugging, or optimizing server-side code running on Vercel. - [Cdn Caching](https://skillsagentes.com/skills/vercel/vercel-plugin/cdn-caching.md): Debug Vercel CDN caching — cache hit rate, stale content, revalidation behavior, ISR + PPR, per-request cache reasons (cacheReason) and PPR state (ppr_state), and costs. - [Eve](https://skillsagentes.com/skills/vercel/vercel-plugin/eve.md): eve framework guidance for durable AI agents and agent-powered applications. Use when creating, editing, or debugging an eve project, when the user explicitly asks for eve, or when the build-agents skill has selected eve as the default framework. Covers eve's filesystem-first runtime, durable sessions, tools, skills, connections, channels, sandboxes, subagents, schedules, evals, frontend clients, and Agent Runs observability. Do not use for incidental agent mentions, generic agent-building prompts, or established non-eve stacks unless the user asks for comparison or migration. ## Skills relacionadas - [Bootstrap](https://skillsagentes.com/skills/vercel/vercel-plugin/bootstrap.md): Project bootstrapping orchestrator for repos that depend on Vercel-linked resources (databases, auth, and managed integrations). Use when setting up or repairing a repository so linking, environment provisioning, env pulls, and first-run db/dev commands happen in the correct safe order. - [Knowledge Update](https://skillsagentes.com/skills/vercel/vercel-plugin/knowledge-update.md): Corrects outdated LLM knowledge about the Vercel platform and introduces new products. Injected at session start. - [Next Forge](https://skillsagentes.com/skills/vercel/vercel-plugin/next-forge.md): next-forge expert guidance — production-grade Turborepo monorepo SaaS starter by Vercel. Use when working in a next-forge project, scaffolding with `npx next-forge init`, or editing @repo/* workspace packages. - [Next Upgrade](https://skillsagentes.com/skills/vercel/vercel-plugin/next-upgrade.md): Upgrade Next.js to the latest version following official migration guides and codemods. Use when upgrading Next.js versions, running codemods, or migrating between major releases. - [Benchmark Agents](https://skillsagentes.com/skills/vercel/vercel-plugin/benchmark-agents.md): Advanced AI agent benchmark scenarios that push Vercel's cutting-edge platform features — Workflow SDK, AI Gateway, MCP, Chat SDK, Queues, Flags, Sandbox, and multi-agent orchestration. Designed to stress-test skill injection for complex, multi-system builds. --- Skills Agentes · [Índice de páginas en markdown](https://skillsagentes.com/sitemap.md) · [Inicio](https://skillsagentes.com/index.md)