after

after を使用すると、レスポンス(またはプリレンダリング)が完了した後に実行する作業をスケジュールできます。これは、ロギングや分析など、レスポンスをブロックすべきではないタスクや副作用に便利です。

サーバーコンポーネントgenerateMetadata を含む)、サーバーアクションルートハンドラミドルウェア で使用できます。

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

import { after } from 'next/server'
// カスタムロギング関数
import { log } from '@/app/utils'

export default function Layout({ children }: { children: React.ReactNode }) {
  after(() => {
    // レイアウトがレンダリングされユーザーに送信された後に実行
    log()
  })
  return <>{children}</>
}

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

リファレンス

パラメータ

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

実行時間

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

補足事項

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

使用例

リクエスト API との併用

サーバーアクションルートハンドラ 内で after と共に cookiesheaders などのリクエスト API を使用できます。これは、変更後のアクティビティをログに記録するのに便利です。例:

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' },
  })
}

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

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

デプロイオプションサポート状況
Node.js サーバ゙ー対応済み
Docker コンテナ対応済み
静的エクスポート非対応
アダプタープラットフォーム依存

Next.js をセルフホスティングする際の after の設定方法 を参照してください。

リファレンス: サーバーレスプラットフォームでの 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))
}

バージョン履歴

バージョン履歴説明
v15.1.0after が安定版になりました。
v15.0.0-rcunstable_after が導入されました。

On this page