Menu

after

after を使用すると、レスポンス(またはプリレンダー)が終了した後に実行される処理をスケジュール設定できます。これはレスポンスをブロックしてはいけないログやアナリティクスなどのタスクや副作用に便利です。

Server ComponentsgenerateMetadata を含む)、Server ActionsRoute HandlersProxy で使用できます。

この関数は、レスポンス(またはプリレンダー)が終了した後に実行されるコールバックを受け入れます:

app/layout.tsx
TypeScript
import { after } from 'next/server'
// カスタムログ関数
import { log } from '@/app/utils'
 
export default function Layout({ children }: { children: React.ReactNode }) {
  after(() => {
    // レイアウトのレンダリング後、ユーザーへ送信された後に実行
    log()
  })
  return <>{children}</>
}

補足: afterDynamic API ではなく、呼び出してもルートが動的にはなりません。静的ページで使用される場合、コールバックはビルド時、またはページが再検証されるたびに実行されます。

Reference

パラメータ

  • レスポンス(またはプリレンダー)が終了した後に実行されるコールバック関数。

Duration

after はプラットフォームのデフォルトまたはルートの設定済み最大継続時間で実行されます。プラットフォームがサポートしている場合、maxDuration ルートセグメント設定を使用してタイムアウト制限を設定できます。

補足

  • after はレスポンスが正常に完了しなかった場合でも実行されます。エラーがスローされた場合、または notFoundredirect が呼び出された場合を含みます。
  • React の cache を使用して、after 内で呼び出された関数を重複排除できます。
  • after は他の after 呼び出しの内側にネストできます。例えば、after 呼び出しをラップして追加機能を追加するユーティリティ関数を作成できます。

Request API と共に使用

Server ActionsRoute Handlersafter 内で、cookiesheaders などの request API を使用できます。これはミューテーション後のアクティビティをログに記録するのに便利です。例えば:

app/api/route.ts
TypeScript
import { after } from 'next/server'
import { cookies, headers } from 'next/headers'
import { logUserAction } from '@/app/utils'
 
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,
    headers: { 'Content-Type': 'application/json' },
  })
}

ただし、Server Componentsafter 内ではこれらの request API を使用できません。これは Next.js が Cache Components をサポートするためにツリーのどの部分が request API にアクセスするかを知る必要があるためですが、after は React のレンダリングライフサイクルの後に実行されます。

プラットフォームサポート

デプロイオプションサポート
Node.js serverYes
Docker containerYes
Static exportNo
AdaptersPlatform-specific

Next.js を自己ホストする場合の after の設定 方法について詳しくお読みください。

Reference: サーバーレスプラットフォームの after サポート

サーバーレスコンテキストで after を使用するには、レスポンスが送信された後に非同期タスクが完了するのを待つ必要があります。Next.js と Vercel では、これは waitUntil(promise) と呼ばれるプリミティブを使用して実現され、サーバーレス呼び出しの有効期間を、waitUntil に渡されたすべての Promise が解決されるまで延長します。

ユーザーが after を実行できるようにしたい場合は、同様に動作する waitUntil の実装を提供する必要があります。

after が呼び出されると、Next.js は次のように waitUntil にアクセスします:

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

これは globalThis[Symbol.for('@next/request-context')] が以下のようなオブジェクトを含むことが予想されることを意味します:

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

実装例を次に示します。

import { AsyncLocalStorage } from 'node:async_hooks'
 
const RequestContextStorage = new AsyncLocalStorage<NextRequestContextValue>()
 
// next.js が使用するアクセサを定義して注入
const RequestContext: NextRequestContext = {
  get() {
    return RequestContextStorage.getStore()
  },
}
globalThis[Symbol.for('@next/request-context')] = RequestContext
 
const handler = (req, res) => {
  const contextValue = { waitUntil: YOUR_WAITUNTIL }
  // 値を提供
  return RequestContextStorage.run(contextValue, () => nextJsHandler(req, res))
}

Version History

Version HistoryDescription
v15.1.0after は安定版になりました。
v15.0.0-rcunstable_after が導入されました。