Capítulo 44 de 456

ISR

Core Idea

Incremental Static Regeneration atualiza conteúdo estático em produção sem rebuild completo do site, combinando páginas prerenderizadas rápidas com revalidação em background. Aplica-se quando não se usa cacheComponents (para isso, ver ISR with Cache Components).

Key Concepts

  • revalidate (route segment config): número em segundos; Next.js invalida o cache no máximo uma vez a cada N segundos.
  • generateStaticParams: lista os params a prerenderizar em build; params não listados são gerados sob demanda (comportamento controlado por dynamicParams).
  • revalidatePath(path): invalida cache de uma rota inteira por caminho; regeneração ocorre na próxima requisição, não imediatamente.
  • revalidateTag(tag, 'max'): invalida todas as entradas de cache com determinada tag; usado com fetch({ next: { tags } }) ou unstable_cache.
  • unstable_cache: cacheia resultado de função (ex.: query de ORM/DB) com revalidate e tags, para casos sem fetch.
  • x-nextjs-cache header: observa comportamento do cache; valores HIT, STALE, MISS, REVALIDATED.
  • NEXT_PRIVATE_DEBUG_CACHE=1: variável de ambiente que faz o servidor logar hits/misses de ISR no console.

Code Examples

// app/blog/[id]/page.tsx
export const revalidate = 60 // invalida no máximo a cada 60s

export async function generateStaticParams() {
  const posts = await fetch('https://api.vercel.app/blog').then(r => r.json())
  return posts.map((post) => ({ id: String(post.id) }))
}

export default async function Page({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params
  const post = await fetch(`https://api.vercel.app/blog/${id}`).then(r => r.json())
  return <main><h1>{post.title}</h1><p>{post.content}</p></main>
}
  • O que demonstra: combinação de revalidate + generateStaticParams para ISR clássico numa rota dinâmica.
// app/actions.ts
'use server'
import { revalidateTag } from 'next/cache'

export async function createPost() {
  revalidateTag('posts', 'max') // invalida tudo marcado com 'posts'
}
  • O que demonstra: invalidação on-demand granular via tag, chamada de dentro de uma Server Action.

Reference Tables

Deployment OptionSuportado
Node.js serverSim
Docker containerSim
Static exportNão
AdaptersDepende da plataforma

Anti-patterns

  • Revalidar com intervalos muito curtos (ex.: 1s): preferir intervalos altos (ex.: 1h); para precisão, usar revalidação on-demand.
  • Depender de Proxy/rewrites em requisições de ISR on-demand: Proxy não executa nesse fluxo; sempre revalidar o caminho exato (/post/1, não /post-1).
  • Assumir que revalidatePath/revalidateTag regeneram imediatamente: eles só invalidam; a regeneração acontece na próxima requisição.
  • Multi-instância sem cache handler compartilhado: revalidação on-demand só afeta a instância que recebeu a chamada.

Key Takeaways

  1. ISR só funciona com runtime Node.js e não é suportado em Static Export.
  2. Se múltiplos fetch numa rota tiverem revalidate diferentes, prevalece o menor tempo para o ISR da rota (mas cada fetch mantém sua própria frequência de cache).
  3. revalidate: 0 ou no-store em qualquer fetch da rota força renderização dinâmica.
  4. Regeneração em background roda na instância que recebeu a requisição disparadora; em billing por-requisição isso conta como compute extra.
  5. x-nextjs-cache e NEXT_PRIVATE_DEBUG_CACHE=1 são as ferramentas primárias para depurar comportamento de cache em produção/local.

Connects To

  • How Revalidation Works (ch043): arquitetura interna de tags e coordenação multi-instância por trás desta página.
  • ISR with Cache Components (ch045): equivalente moderno quando cacheComponents está habilitado.
  • cacheHandlers: configuração de cache handler customizado para persistir/compartilhar cache entre instâncias.