after

after permite programar tareas para que se ejecuten después de que se complete una respuesta (o prerenderizado). Esto es útil para tareas y otros efectos secundarios que no deberían bloquear la respuesta, como registro de logs y análisis.

Puede usarse en Componentes de Servidor (incluyendo generateMetadata), Acciones de Servidor, Manejadores de Ruta y Middleware.

La función acepta un callback que se ejecutará después de que la respuesta (o prerenderizado) se complete:

import { after } from 'next/server'
// Función personalizada de logging
import { log } from '@/app/utils'

export default function Layout({ children }: { children: React.ReactNode }) {
  after(() => {
    // Se ejecuta después de que el layout se renderice y envíe al usuario
    log()
  })
  return <>{children}</>
}

Importante: after no es una API Dinámica y llamarla no convierte una ruta en dinámica. Si se usa en una página estática, el callback se ejecutará en tiempo de compilación o cuando la página se revalide.

Referencia

Parámetros

  • Una función callback que se ejecutará después de que la respuesta (o prerenderizado) se complete.

Duración

after se ejecutará durante la duración máxima configurada por defecto en la plataforma para tu ruta. Si tu plataforma lo soporta, puedes configurar el límite de tiempo usando la configuración de segmento de ruta maxDuration.

Aspectos importantes

  • after se ejecutará incluso si la respuesta no se completó correctamente, incluyendo cuando se lanza un error o cuando se llama a notFound o redirect.
  • Puedes usar cache de React para deduplicar funciones llamadas dentro de after.
  • after puede anidarse dentro de otras llamadas after, por ejemplo, puedes crear funciones utilitarias que envuelvan llamadas after para añadir funcionalidad adicional.

Ejemplos

Con APIs de solicitud

Puedes usar APIs de solicitud como cookies y headers dentro de after en Acciones de Servidor y Manejadores de Ruta. Esto es útil para registrar actividad después de una mutación. Por ejemplo:

import { after } from 'next/server'
import { cookies, headers } from 'next/headers'
import { logUserAction } from '@/app/utils'

export async function POST(request: Request) {
  // Realizar mutación
  // ...

  // Registrar actividad del usuario para análisis
  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,
    headers: { 'Content-Type': 'application/json' },
  })
}

Sin embargo, no puedes usar estas APIs de solicitud dentro de after en Componentes de Servidor. Esto se debe a que Next.js necesita saber qué parte del árbol accede a las APIs de solicitud para soportar Prerenderizado Parcial, pero after se ejecuta después del ciclo de vida de renderizado de React.

Soporte de Plataforma

Opción de DespliegueSoporte
Servidor Node.js
Contenedor Docker
Exportación estáticaNo
AdaptadoresDepende de la plataforma

Aprende cómo configurar after al autoalojar Next.js.

Referencia: soporte de after para plataformas serverless Usar after en un contexto serverless requiere esperar a que las tareas asíncronas finalicen después de enviar la respuesta. En Next.js y Vercel, esto se logra usando un primitivo llamado waitUntil(promise), que extiende el tiempo de vida de una invocación serverless hasta que todas las promesas pasadas a waitUntil se resuelvan.

Si deseas que tus usuarios puedan ejecutar after, deberás proporcionar tu propia implementación de waitUntil que funcione de manera análoga.

Cuando se llama a after, Next.js accederá a waitUntil así:

const RequestContext = globalThis[Symbol.for('@next/request-context')]
const contextValue = RequestContext?.get()
const waitUntil = contextValue?.waitUntil

Lo que significa que se espera que globalThis[Symbol.for('@next/request-context')] contenga un objeto como este:

type NextRequestContext = {
  get(): NextRequestContextValue | undefined
}

type NextRequestContextValue = {
  waitUntil?: (promise: Promise<any>) => void
}

Aquí hay un ejemplo de implementación.

import { AsyncLocalStorage } from 'node:async_hooks'

const RequestContextStorage = new AsyncLocalStorage<NextRequestContextValue>()

// Definir e inyectar el accesor que next.js usará
const RequestContext: NextRequestContext = {
  get() {
    return RequestContextStorage.getStore()
  },
}
globalThis[Symbol.for('@next/request-context')] = RequestContext

const handler = (req, res) => {
  const contextValue = { waitUntil: YOUR_WAITUNTIL }
  // Proporcionar el valor
  return RequestContextStorage.run(contextValue, () => nextJsHandler(req, res))
}

Historial de Versiones

Historial de VersionesDescripción
v15.1.0after se volvió estable.
v15.0.0-rcSe introdujo unstable_after.

On this page