Skills Agentes

Next Cache Components

Guía sobre Cache Components de Next.js 16: PPR, directiva `use cache`, cacheLife, cacheTag, updateTag y migración desde unstable_cache.

Oficial

Reemplaza a: unstable_cache, experimental.ppr

Estrellas
287

en todo el repo

Actividad
34

0–100, la ruta de este skill

Actualizado
hace 6 meses

último commit aquí

Commits
0

últimos 90 días

Contexto
2.9k tok

61 tok en reposo

Paquete
3 archivos

23 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add vercel/vercel-plugin --skill next-cache-components --agent claude-code

Se instala solo en este repositorio.

Qué hace

  • Explica cómo activar Cache Components (`cacheComponents: true`) para Partial Prerendering en Next.js 16
  • Guía el uso de la directiva `use cache` a nivel de archivo, componente o función
  • Detalla `cacheLife()`, `cacheTag()`, `updateTag()` y `revalidateTag()` para invalidación de caché
  • Ofrece una tabla de migración desde `unstable_cache` y flags experimentales antiguos hacia `use cache`
  • Señala limitaciones: sin soporte en Edge runtime, sin static export, y valores no deterministas

Úsalo cuando

  • Al implementar partial prerendering (PPR) en una app Next.js
  • Al definir estrategias de caché con `use cache`, `cacheLife` o `cacheTag`
  • Al migrar código que usa `unstable_cache` o `experimental.ppr` a Next.js 16
  • Al invalidar caché con `updateTag` o `revalidateTag`

No lo uses cuando

    Qué lo activa

    Di cualquiera de estas frases y el agente debería cargar este skill.

    • “Cómo activo Partial Prerendering en Next.js 16”
    • “Migra este `unstable_cache` a la directiva `use cache`”
    • “Necesito invalidar el caché de productos con cacheTag”
    • “Configura cacheLife para que los datos se revaliden cada hora”

    SKILL.md

    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

    // 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:

    export default function Page() {
      return (
        <header>
          <h1>Our Blog</h1>  {/* Static - instant */}
          <nav>...</nav>
        </header>
      )
    }
    

    2. Cached (use cache)

    Async data that doesn't need fresh fetches every request:

    async function BlogPosts() {
      'use cache'
      cacheLife('hours')
    
      const posts = await db.posts.findMany()
      return <PostList posts={posts} />
    }
    

    3. Dynamic (Suspense)

    Runtime data that must be fresh - wrap in Suspense:

    import { Suspense } from 'react'
    
    export default function Page() {
      return (
        <>
          <BlogPosts />  {/* Cached */}
    
          <Suspense fallback={<p>Loading...</p>}>
            <UserPreferences />  {/* Dynamic - streams in */}
          </Suspense>
        </>
      )
    }
    
    async function UserPreferences() {
      const theme = (await cookies()).get('theme')?.value
      return <p>Theme: {theme}</p>
    }
    

    use cache Directive

    File Level

    'use cache'
    
    export default async function Page() {
      // Entire page is cached
      const data = await fetchData()
      return <div>{data}</div>
    }
    

    Component Level

    export async function CachedComponent() {
      'use cache'
      const data = await fetchData()
      return <div>{data}</div>
    }
    

    Function Level

    export async function getData() {
      'use cache'
      return db.query('SELECT * FROM posts')
    }
    

    Cache Profiles

    Built-in Profiles

    'use cache'                    // Default: 5m stale, 15m revalidate
    
    'use cache: remote'           // Platform-provided cache (Redis, KV)
    
    'use cache: private'          // For compliance, allows runtime APIs
    

    cacheLife() - Custom Lifetime

    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

    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

    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:

    '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:

    '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

    // Wrong - runtime API inside use cache
    async function CachedProfile() {
      'use cache'
      const session = (await cookies()).get('session')?.value  // Error!
      return <div>{session}</div>
    }
    
    // Correct - extract outside, pass as argument
    async function ProfilePage() {
      const session = (await cookies()).get('session')?.value
      return <CachedProfile sessionId={session} />
    }
    
    async function CachedProfile({ sessionId }: { sessionId: string }) {
      'use cache'
      // sessionId becomes part of cache key automatically
      const data = await fetchUserData(sessionId)
      return <div>{data.name}</div>
    }
    

    Exception: use cache: private

    For compliance requirements when you can't refactor:

    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
    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

    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 */}
          <header><h1>Dashboard</h1></header>
          <nav>...</nav>
    
          {/* Cached - fast, revalidates hourly */}
          <Stats />
    
          {/* Dynamic - streams in with fresh data */}
          <Suspense fallback={<NotificationsSkeleton />}>
            <Notifications />
          </Suspense>
        </>
      )
    }
    
    async function Stats() {
      'use cache'
      cacheLife('hours')
      cacheTag('dashboard-stats')
    
      const stats = await db.stats.aggregate()
      return <StatsDisplay stats={stats} />
    }
    
    async function Notifications() {
      const userId = (await cookies()).get('userId')?.value
      const notifications = await db.notifications.findMany({
        where: { userId, read: false }
      })
      return <NotificationList items={notifications} />
    }
    

    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):

    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 <div>{user.name}</div>
    }
    

    After (use cache):

    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 <div>{user.name}</div>
    }
    

    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:

    import { connection } from 'next/server'
    
    async function DynamicContent() {
      await connection()  // Defer to request time
      const id = crypto.randomUUID()  // Different per request
      return <div>{id}</div>
    }
    

    Sources:

    Reproducido de vercel/vercel-plugin bajo licencia NOASSERTION. Leer esta página en markdown.

    Archivos

    3 archivos en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

    Antes de instalar

    Requiere Next.js 16 y runtime Node.js (no soporta Edge runtime ni static export).

    Detalles

    Creador
    vercel
    Licencia
    NOASSERTION
    Recursos incluidos
    Incluye scripts o referencias
    Código fuente
    Ver SKILL.md

    Etiquetas

    Más de vercel/vercel-plugin

    Este repo incluye 43 skills. Si instalas uno, normalmente ya tienes los demás. Ver el pack vercel-plugin entero y su comando de instalación

    Corrige el conocimiento desactualizado del LLM sobre la plataforma Vercel e introduce sus productos nuevos. Se inyecta al inicio de la sesión.

    Costo de contexto al activarse
    1.8k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    Oficialdevops infraestructura

    Guía experta de Vercel Connect: obtén tokens OAuth con permisos limitados para servicios de terceros (Slack, GitHub, servidores MCP, OAuth, Snowflake) en nombre de apps o usuarios vía Vercel OIDC.

    Costo de contexto al activarse
    4.8k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    Oficialdesarrollo apis

    Depura el caching de la CDN de Vercel: tasa de aciertos, contenido obsoleto, revalidación, ISR + PPR, cacheReason, ppr_state y costos.

    Costo de contexto al activarse
    5.2k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 2 meses
    Oficialdevops infraestructura

    Guía experta sobre Vercel Functions: Serverless Functions, Edge Functions, Fluid Compute, streaming, Cron Jobs y configuración de runtime para código server-side en Vercel.

    Costo de contexto al activarse
    5.6k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    Oficialdevops infraestructura

    Guía de arquitectura backend: úsala para planear, construir o migrar una API o backend, elegir entre Functions, Services, contenedores, Workflow, Queues y bases de datos de Marketplace, o seleccionar framework y runtime.

    Costo de contexto al activarse
    1.5k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    el mes pasado
    Oficialdesarrollo apis

    Eve

    287

    Guía de eve, el framework para agentes de IA duraderos: runtime basado en filesystem, sesiones, tools, skills, canales, sandboxes, subagentes, schedules, evals y observabilidad con Agent Runs.

    Costo de contexto al activarse
    1.5k tok
    Tamaño del paquete
    3 archivos
    Última actualización
    el mes pasado
    Oficialherramientas desarrollo

    Skills relacionados

    Guía por defecto para construir agentes de IA: eve es la mejor opción por defecto — ejecuta init y luego lee la documentación incluida.

    Costo de contexto al activarse
    1.4k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    Oficialherramientas desarrollo

    Eve

    287

    Guía de eve, el framework para agentes de IA duraderos: runtime basado en filesystem, sesiones, tools, skills, canales, sandboxes, subagentes, schedules, evals y observabilidad con Agent Runs.

    Costo de contexto al activarse
    1.5k tok
    Tamaño del paquete
    3 archivos
    Última actualización
    el mes pasado
    Oficialherramientas desarrollo

    Buenas prácticas de Next.js: convenciones de archivos, límites de RSC, patrones de datos, APIs async, metadata, manejo de errores, route handlers, optimización de imágenes/fuentes y bundling.

    Costo de contexto al activarse
    1k tok
    Tamaño del paquete
    21 archivos
    Última actualización
    hace 6 meses
    Oficialherramientas desarrollo