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}</>
}
import { after } from 'next/server'
// Función personalizada de logging
import { log } from '@/app/utils'
export default function Layout({ children }) {
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 anotFound
oredirect
.- Puedes usar
cache
de React para deduplicar funciones llamadas dentro deafter
. after
puede anidarse dentro de otras llamadasafter
, por ejemplo, puedes crear funciones utilitarias que envuelvan llamadasafter
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' },
})
}
import { after } from 'next/server'
import { cookies, headers } from 'next/headers'
import { logUserAction } from '@/app/utils'
export async function POST(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 Despliegue | Soporte |
---|---|
Servidor Node.js | Sí |
Contenedor Docker | Sí |
Exportación estática | No |
Adaptadores | Depende de la plataforma |
Aprende cómo configurar after
al autoalojar Next.js.
Referencia: soporte de
Usar after
para plataformas serverlessafter
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 Versiones | Descripción |
---|---|
v15.1.0 | after se volvió estable. |
v15.0.0-rc | Se introdujo unstable_after . |