コンテンツにスキップ

after

after を使用すると、レスポンス(またはプリレンダリング)が完了した後に実行する処理をスケジュールできます。これは、ロギングやアナリティクスなど、レスポンスをブロックすべきでないタスクやその他の副作用に役立ちます。

generateMetadata を含む Server Components、Server Actions、Route Handlers、Proxy で使用できます。

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

app/layout.tsx
import { after } from 'next/server'
// Custom logging function
import { log } from '@/app/utils'
 
export default function Layout({ children }: { children: React.ReactNode }) {
  after(() => {
    // Execute after the layout is rendered and sent to the user
    log()
  })
  return <>{children}</>
}

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

リファレンス

Parameters

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

実行時間

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

Good to know

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

リクエストAPIを使用した場合

Server Actions および Route Handlers では、after 内で cookiesheaders などのリクエスト API を使用できます。これは、ミューテーション後のアクティビティをロギングするのに役立ちます。例:

app/api/route.ts
import { after } from 'next/server'
import { cookies, headers } from 'next/headers'
import { logUserAction } from '@/app/utils'
 
export async function POST(request: Request) {
  // Perform mutation
  // ...
 
  // Log user activity for analytics
  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 Components の after 内ではこれらのリクエスト API を使用できません。これは、Next.js が Cache Components をサポートするために、リクエスト API にアクセスするツリーのどの部分を知る必要があるためですが、after は React のレンダリングライフサイクルの後に実行されます。

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

デプロイメントオプションサポート
Node.jsサーバーはい
Dockerコンテナはい
静的エクスポートいいえ
アダプタープラットフォーム固有

Next.js をセルフホストする際の after の設定方法を学んでください。

リファレンス: サーバーレスプラットフォーム向けの after のサポート

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

ユーザーに 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>()
 
// Define and inject the accessor that next.js will use
const RequestContext: NextRequestContext = {
  get() {
    return RequestContextStorage.getStore()
  },
}
globalThis[Symbol.for('@next/request-context')] = RequestContext
 
const handler = (req, res) => {
  const contextValue = { waitUntil: YOUR_WAITUNTIL }
  // Provide the value
  return RequestContextStorage.run(contextValue, () => nextJsHandler(req, res))
}

バージョン履歴

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