after
after
は、レスポンス(またはプリレンダリング)が完了した後に実行される作業をスケジュールすることを可能にします。これは、ログ記録や分析など、レスポンスをブロックすべきでないタスクや他の副作用に役立ちます。
これはServer Components(generateMetadata
を含む)、Server Actions、Route Handlers、およびMiddlewareで使用できます。
この関数は、レスポンス(またはプリレンダリング)が完了した後に実行されるコールバックを受け取ります:
- TypeScript
- JavaScript
import { after } from 'next/server'
// カスタムログ関数
import { log } from '@/app/utils'
export default function Layout({ children }: { children: React.ReactNode }) {
after(() => {
// レイアウトがレンダリングされ、ユーザーに送信された後に実行されます
log()
})
return <>{children}</>
}
import { after } from 'next/server'
// カスタムログ関数
import { log } from '@/app/utils'
export default function Layout({ children }) {
after(() => {
// レイアウトがレンダリングされ、ユーザーに送信された後に実行されます
log()
})
return <>{children}</>
}
Good to know:
after
はDynamic APIではなく、これを呼び出してもルートが動的になることはありません。静的ページ内で使用される場合、コールバックはビルド時またはページが再検証されるたびに実行されます。
リファレンス
パラメータ
- レスポンス(またはプリレンダリング)が完了した後に実行されるコールバック関数
実行時間
after
は、プラットフォームのデフォルトまたは設定されたルートの最大実行時間で実行されます。プラットフォームがサポートしている場合、maxDuration
ルートセグメント設定を使用してタイムアウト制限を設定できます。
Good to know
after
は、レスポンスが正常に完了しなかった場合でも実行されます。エラーがスローされた場合やnotFound
やredirect
が呼び出された場合も含まれます。- Reactの
cache
を使用して、after
内で呼び出される関数を重複排除できます。 after
は他のafter
呼び出し内にネストすることができ、例えば、追加の機能を追加するためにafter
呼び出しをラップするユーティリティ関数を作成できます。
代替案
after
の使用ケースは、主要なレスポンスをブロックせずに二次的なタスクを処理することです。これは、プラットフォームのwaitUntil()
を使用するか、プロミスからawait
を削除することに似ていますが、次の違いがあります:
waitUntil()
: プロミスを受け取り、リクエストのライフサイクル中に実行されるタスクをキューに入れますが、after
はレスポンスが完了した後に実行されるコールバックを受け取ります。await
を削除する: レスポンス中に実行を開始し、リソースを使用します。サーバーレス環境では、レスポンスが送信された直後に関数が計算を停止するため、タスクが中断される可能性があり、信頼性がありません。
after
は他のNext.jsのAPIやコンテキストを考慮して設計されているため、使用をお勧めします。
例
リクエストAPIと共に使用する場合
Server ActionsやRoute Handlers内で、after
内でcookies
やheaders
などのリクエストAPIを使用できます。これは、ミューテーション後のアクティビティをログに記録するのに役立ちます。例えば:
- TypeScript
- JavaScript
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' },
})
}
import { after } from 'next/server'
import { cookies, headers } from 'next/headers'
import { logUserAction } from '@/app/utils'
export async function POST(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 Components内のafter
ではこれらのリクエストAPIを使用することはできません。これは、Next.jsがPartial Prerenderingをサポートするために、どの部分のtreeがリクエストAPIにアクセスするかを知る必要があるためですが、after
はReactのレンダリングライフサイクルの後に実行されます。
バージョン履歴 | 説明 |
---|---|
v15.1.0 | after が安定版になりました |
v15.0.0-rc | unstable_after が導入されました |