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}</>
}
import { after } from 'next/server'
// Пользовательская функция логирования
import { log } from '@/app/utils'
export default function Layout({ children }) {
after(() => {
// Выполняется после рендеринга макета и отправки пользователю
log()
})
return <>{children}</>
}
Важно знать:
after
не является Динамическим API, и её вызов не делает маршрут динамическим. Если она используется в статической странице, колбэк выполнится во время сборки или при ревалидации страницы.
Справочник
Параметры
- Колбэк-функция, которая будет выполнена после завершения ответа (или предварительного рендеринга).
Длительность
after
будет выполняться в течение стандартного или настроенного максимального времени выполнения маршрута для вашей платформы. Если платформа поддерживает это, вы можете настроить лимит времени с помощью конфигурации сегмента маршрута maxDuration
.
Важно знать
after
будет выполнена даже если ответ не завершился успешно, включая случаи возникновения ошибки или вызоваnotFound
/redirect
.- Вы можете использовать React
cache
для дедупликации функций, вызываемых внутриafter
. after
может быть вложена в другие вызовыafter
. Например, вы можете создавать утилитные функции, оборачивающие вызовыafter
для добавления дополнительной функциональности.
Примеры
С API запросов
Вы можете использовать API запросов, такие как cookies
и headers
, внутри after
в Серверных Действиях и Обработчиках Маршрутов. Это полезно для логирования активности после мутации. Например:
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' },
})
}
Однако вы не можете использовать эти API запросов внутри after
в Серверных Компонентах. Это связано с тем, что Next.js должен знать, какая часть дерева обращается к API запросов для поддержки Частичного Предварительного Рендеринга, но after
выполняется после жизненного цикла рендеринга React.
Поддержка платформ
Вариант развертывания | Поддержка |
---|---|
Сервер Node.js | Да |
Docker контейнер | Да |
Статический экспорт | Нет |
Адаптеры | Зависит от платформы |
Узнайте, как настроить after
при самостоятельном хостинге Next.js.
Справочник: поддержка
Использование after
для serverless-платформafter
в serverless-контексте требует ожидания завершения асинхронных задач после отправки ответа. В Next.js и Vercel это достигается с помощью примитива waitUntil(promise)
, который продлевает время жизни serverless-вызова до завершения всех промисов, переданных в 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>()
// Определяем и внедряем аксессор, который будет использовать 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.0 | after стала стабильной. |
v15.0.0-rc | Введена unstable_after . |