Capítulo 152 de 456

after

Core Idea

after agenda trabalho para executar depois que a resposta (ou o prerender) já terminou, sem bloquear o retorno ao usuário. Serve para logging, analytics e outros efeitos colaterais que não precisam atrasar a resposta.

Key Concepts

  • after(callback): importado de next/server; roda o callback após a resposta (ou prerender) ser finalizada.
  • Não é Request-time API: chamar after não torna a rota dinâmica; em página estática o callback roda no build ou na revalidação.
  • Escopos suportados: Server Components (inclusive generateMetadata), Server Functions, Route Handlers e Proxy.
  • Duration: after roda pelo tempo máximo padrão/configurado da plataforma; ajustável via maxDuration no route segment config.
  • waitUntil: primitiva usada internamente (via globalThis[Symbol.for('@next/request-context')]) para estender a vida da invocação serverless até as promises de after resolverem.

Code Examples

import { after } from 'next/server'
import { log } from '@/app/utils'

export default function Layout({ children }: { children: React.ReactNode }) {
  after(() => {
    log()
  })
  return <>{children}</>
}
  • O que demonstra: uso básico em um Server Component (layout), executando log depois do render.
// Route Handler / Server Function: cookies/headers funcionam direto dentro do after
export async function POST(request: Request) {
  after(async () => {
    const userAgent = (await headers()).get('user-agent') || 'unknown'
    const sessionCookie = (await cookies()).get('session-id')?.value || 'anonymous'
    logUserAction({ sessionCookie, userAgent })
  })
  return new Response(JSON.stringify({ status: 'success' }), { status: 200 })
}
  • O que demonstra: em Route Handlers e Server Functions, cookies/headers podem ser lidos dentro do callback do after.
// Server Component: ler request data ANTES do after, nunca dentro
export default async function Page() {
  const userAgent = (await headers()).get('user-agent') || 'unknown'
  const sessionCookie = (await cookies()).get('session-id')?.value || 'anonymous'
  after(() => {
    logUserAction({ sessionCookie, userAgent })
  })
  return <h1>My Page</h1>
}
  • O que demonstra: em Server Components, chamar cookies()/headers() dentro do callback lança erro em runtime; leia antes e passe por closure.

Reference Tables

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

Anti-patterns

  • Chamar cookies()/headers() dentro do callback em Server Component: lança erro em runtime; leia os dados antes do after e passe por closure.
  • Assumir que after bloqueia notFound/redirect: after executa mesmo se a resposta terminar com erro, notFound() ou redirect().

Key Takeaways

  1. after não muda a natureza estática/dinâmica da rota, só adia efeitos colaterais.
  2. Em Cache Components, componentes que leem request data dentro de after devem estar isolados em um componente dinâmico envolto por <Suspense>.
  3. after pode ser aninhado dentro de outros after, útil para criar wrappers utilitários.
  4. Use React cache para deduplicar funções chamadas dentro de múltiplos after.
  5. Self-hosting requer implementar waitUntil manualmente para suportar after em ambiente serverless.

Connects To

  • maxDuration: controla o timeout dentro do qual o after deve terminar.
  • cookies, headers: Request-time APIs cujo uso dentro de after depende do contexto de execução.
  • Cache Components / Suspense: padrão para combinar dados dinâmicos com after em rotas prerenderizadas.