| Situação | Use | Porquê |
|---|---|---|
| Busca dado, usa secret/DB, sem estado/evento | Server Component (padrão) | Não entra no bundle do cliente |
Precisa de useState/useEffect/evento/API de browser | Client Component ("use client") | Só roda no browser |
| Página majoritariamente estática + 1 pedaço interativo | Server pai + Client filho isolado | Marca só a fronteira mínima com "use client" |
| Server Component dentro de Client Component | Passe como children/prop JSX, nunca import direto | Mantém o Server Component fora do module graph do cliente |
| Precisa de | Use | Nota |
|---|---|---|
Cachear resultado de fetch() | cache: 'force-cache' (default sob Cache Components é sem cache) | Web fetch estendida com next.revalidate/next.tags |
| Cachear função/componente async não-fetch (ORM, DB) | "use cache" + cacheLife()/cacheTag() | Nível de dado ou de UI |
| Cache por-usuário (cookies/headers) | "use cache: private" | Cacheado só no browser do usuário |
| Cache compartilhado entre instâncias self-hosted | "use cache: remote" + cacheHandler custom | Precisa storage externo (Redis etc.) |
| Revalidar por tempo (ISR clássico) | revalidate no fetch/route segment ou cacheLife profile | stale-while-revalidate |
| Revalidar sob demanda (webhook de CMS) | revalidateTag()/revalidatePath() | Serve stale enquanto revalida em background |
| Refletir mutação na hora (read-your-own-writes) | updateTag() (só em Server Actions) | Expira na hora, próximo read paga o recompute |
| Cache legado não determinístico | unstable_cache | Pré-Cache Components; prefira use cache em projetos novos |
| Situação | Use |
|---|---|
| Set finito e conhecido de params (produtos, posts) | generateStaticParams prerenderiza no build |
| Params ilimitados, mas alguns conhecidos | generateStaticParams parcial + dynamicParams: true (default) gera o resto sob demanda |
| Só páginas listadas podem existir | dynamicParams: false → 404 pros não listados |
| Dado muda a cada request | Sem generateStaticParams; deixe dinâmico |
| Precisa de | Use | Porquê |
|---|---|---|
| Endpoint consumido por client externo/webhook/mobile app | Route Handler (route.js) | Web Request/Response padrão, URL pública |
| Mutação disparada de dentro de um form/componente React | Server Action ("use server") | Chamada RPC direta, sem definir endpoint |
| GET cacheável, servido como API pública | Route Handler + "use cache" | Route Handlers suportam cache desde v15+ |
| Upload de form com progressive enhancement | Server Action + <Form>/useActionState | Funciona sem JS, integra com pending state |
| Situação | Use |
|---|---|
| Projeto novo | App Router (app/) — padrão desde v13 |
| App legado grande, migração progressiva | Coexistência app/+pages/ (App tem precedência), migrar rota por rota |
getInitialProps/_app/_document/_error | Só existe no Pages Router |
| Server Components, streaming, PPR, Cache Components | Só existe no App Router |
| Arquivo | Função |
|---|---|
page.js | UI de uma rota; sempre a folha (leaf) da subárvore |
layout.js | UI compartilhada entre um segmento e seus filhos, preserva estado na navegação |
template.js | Como layout.js, mas remonta (key nova) a cada navegação |
loading.js | Envolve page.js num <Suspense> automático |
error.js | Error boundary de Client Component para o segmento |
global-error.js | Error boundary do root layout; precisa <html>/<body> próprios |
not-found.js | UI de 404, disparada por notFound() |
route.js | Route Handler (endpoint HTTP), não pode coexistir com page.js no mesmo segmento |
default.js | Fallback de slot de Parallel Route em hard navigation |
middleware.ts/proxy.ts | Roda antes da request completar (renomeado pra proxy.ts na v16) |
| Situação | Use |
|---|---|
| Deploy simples com Node.js persistente | next build && next start |
| Docker / container mínimo | output: 'standalone' — gera server.js + só os arquivos tracados |
| Host estático sem servidor Node (sem SSR/ISR/Route Handlers dinâmicos) | output: 'export' — HTML/CSS/JS puro em out/ |
| Múltiplas instâncias atrás de load balancer | cacheHandler compartilhado + deploymentId/generateBuildId consistente (evita version skew) |
| Plataforma não-Vercel com CDN própria | Verified Adapter (adapterPath) se existir; senão Node.js server genérico |
| Objetivo | Modelo |
|---|---|
| Página idêntica pra todos, pode ficar em CDN | Static (prerender no build ou primeira request) |
| Página muda por request (auth, dado real-time) | Dynamic — usa cookies()/headers()/connection() ou não tem "use cache" |
| Mistura de estático (header/shell) + dinâmico (widget de usuário) | Cache Components: componente dinâmico dentro de <Suspense>, resto no static shell (PPR) |