after

after permet de planifier l'exécution de tâches après la fin d'une réponse (ou d'un prérendu). C'est utile pour les tâches et autres effets secondaires qui ne devraient pas bloquer la réponse, comme les logs et les analyses.

Elle peut être utilisée dans les Composants Serveur (y compris generateMetadata), les Actions Serveur, les Gestionnaires de Route, et le Middleware.

La fonction accepte une callback qui sera exécutée après la fin de la réponse (ou du prérendu) :

import { after } from 'next/server'
// Fonction de log personnalisée
import { log } from '@/app/utils'

export default function Layout({ children }: { children: React.ReactNode }) {
  after(() => {
    // Exécuté après que le layout soit rendu et envoyé à l'utilisateur
    log()
  })
  return <>{children}</>
}

Bon à savoir : after n'est pas une API Dynamique et son appel ne rend pas une route dynamique. Si elle est utilisée dans une page statique, la callback s'exécutera au moment du build, ou à chaque revalidation de page.

Référence

Paramètres

  • Une fonction callback qui sera exécutée après la fin de la réponse (ou du prérendu).

Durée

after s'exécutera pendant la durée maximale par défaut de la plateforme ou configurée pour votre route. Si votre plateforme le supporte, vous pouvez configurer la limite de timeout en utilisant la config de segment de route maxDuration.

Bon à savoir

  • after s'exécutera même si la réponse ne s'est pas terminée avec succès. Y compris lorsqu'une erreur est levée ou que notFound ou redirect est appelé.
  • Vous pouvez utiliser cache de React pour dédupliquer les fonctions appelées dans after.
  • after peut être imbriqué dans d'autres appels after, par exemple pour créer des fonctions utilitaires qui encapsulent des appels after pour ajouter des fonctionnalités supplémentaires.

Exemples

Avec les APIs de requête

Vous pouvez utiliser les APIs de requête comme cookies et headers dans after pour les Actions Serveur et les Gestionnaires de Route. C'est utile pour logger des activités après une mutation. Par exemple :

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

export async function POST(request: Request) {
  // Effectuer la mutation
  // ...

  // Logger l'activité utilisateur pour les analyses
  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' },
  })
}

Cependant, vous ne pouvez pas utiliser ces APIs de requête dans after pour les Composants Serveur. En effet, Next.js a besoin de savoir quelle partie de l'arbre accède aux APIs de requête pour supporter le Prérendu Partiel, mais after s'exécute après le cycle de rendu de React.

Support des Plateformes

Option de DéploiementSupporté
Serveur Node.jsOui
Conteneur DockerOui
Export StatiqueNon
AdaptateursDépend de la plateforme

Apprenez comment configurer after pour un hébergement autonome de Next.js.

Référence : support de after pour les plateformes serverless L'utilisation de after dans un contexte serverless nécessite d'attendre la fin des tâches asynchrones après l'envoi de la réponse. Dans Next.js et Vercel, cela est réalisé avec une primitive appelée waitUntil(promise), qui prolonge la durée d'une invocation serverless jusqu'à ce que toutes les promesses passées à waitUntil soient résolues.

Si vous souhaitez que vos utilisateurs puissent utiliser after, vous devrez fournir votre propre implémentation de waitUntil qui se comporte de manière analogue.

Lorsque after est appelée, Next.js accédera à waitUntil comme ceci :

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

Ce qui signifie que globalThis[Symbol.for('@next/request-context')] est censé contenir un objet comme ceci :

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

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

Voici un exemple d'implémentation.

import { AsyncLocalStorage } from 'node:async_hooks'

const RequestContextStorage = new AsyncLocalStorage<NextRequestContextValue>()

// Définir et injecter l'accesseur que next.js utilisera
const RequestContext: NextRequestContext = {
  get() {
    return RequestContextStorage.getStore()
  },
}
globalThis[Symbol.for('@next/request-context')] = RequestContext

const handler = (req, res) => {
  const contextValue = { waitUntil: YOUR_WAITUNTIL }
  // Fournir la valeur
  return RequestContextStorage.run(contextValue, () => nextJsHandler(req, res))
}

Historique des Versions

Historique des VersionsDescription
v15.1.0after devient stable.
v15.0.0-rcunstable_after introduite.

On this page