Functions: after
Functions: after | Next.js
섹션 제목: “Functions: after | Next.js”Source URL: https://nextjs.org/docs/app/api-reference/functions/after
Copy page
after
섹션 제목: “after”Last updated February 20, 2026
after는 응답(또는 사전 렌더링)이 완료된 뒤에 실행할 작업을 예약할 수 있게 해 줍니다. 이는 로깅, 분석처럼 응답을 차단하면 안 되는 작업 및 부수 효과에 유용합니다.
Server Components(generateMetadata 포함), Server Functions, Route Handlers, Proxy에서 사용할 수 있습니다.
이 함수는 응답(또는 사전 렌더링)이 끝난 후 실행될 콜백을 받습니다:
app/layout.tsx
JavaScriptTypeScript
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가 아니며, 이를 호출해도 라우트가 동적으로 변하지 않습니다. 정적 페이지에서 사용하면 콜백은 빌드 시점 또는 페이지가 재검증될 때 실행됩니다.
Reference
섹션 제목: “Reference”Parameters
섹션 제목: “Parameters”- 응답(또는 사전 렌더링)이 완료된 뒤 실행될 콜백 함수.
Duration
섹션 제목: “Duration”after는 라우트에 설정된 플랫폼 기본값 또는 구성된 최대 기간 동안 실행됩니다. 플랫폼이 지원한다면 maxDuration 라우트 세그먼트 구성을 사용해 타임아웃 한도를 설정할 수 있습니다.
Good to know
섹션 제목: “Good to know”- 응답이 정상적으로 완료되지 않아도
after는 실행됩니다. 오류가 발생하거나notFound,redirect가 호출된 경우도 포함됩니다. after내부에서 호출되는 함수를 중복 제거하려면 Reactcache를 사용할 수 있습니다.after는 다른after호출 안에 중첩할 수 있습니다. 예를 들어, 추가 기능을 붙이기 위해after호출을 감싸는 유틸리티 함수를 만들 수 있습니다.
Examples
섹션 제목: “Examples”With request APIs
섹션 제목: “With request APIs”cookies나 headers 같은 요청 API를 after 내부에서 사용할 수 있는지는 after가 어디에서 호출되는지에 따라 달라집니다.
In Route Handlers and Server Functions
섹션 제목: “In Route Handlers and Server Functions”Route Handlers, Server Functions에서는 after 콜백 안에서 cookies, headers를 직접 호출할 수 있습니다. 이는 변형이나 API 요청 뒤에 활동을 기록할 때 유용합니다. 예:
app/api/route.ts
JavaScriptTypeScript
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' }, }) }In Server Components (pages and layouts)
섹션 제목: “In Server Components (pages and layouts)”Server Components(페이지, 레이아웃, generateMetadata 포함)에서는 after 내부에서 cookies, headers, 기타 Dynamic APIs를 사용할 수 없습니다. Next.js가 Partial Prerendering과 Cache Components를 지원하려면 컴포넌트 트리의 어떤 부분이 요청 데이터를 읽는지 알아야 하지만, after는 React 렌더링 라이프사이클 이후에 실행되기 때문입니다.
Server Component에서 after 콜백에 요청 데이터가 필요하다면 먼저 읽은 뒤 값을 전달하세요:
app/page.tsx
JavaScriptTypeScript
import { after } from 'next/server' import { cookies, headers } from 'next/headers' import { logUserAction } from '@/app/utils'
export default async function Page() { // Read request data before `after` — this is allowed // These calls will be read during the component's rendering lifecycle const userAgent = (await headers()).get('user-agent') || 'unknown' const sessionCookie = (await cookies()).get('session-id')?.value || 'anonymous'
after(() => { // Use the values read above logUserAction({ sessionCookie, userAgent }) })
return <h1>My Page</h1> }Server Component에서 after 콜백 내부에서 cookies()나 headers()를 호출하면 런타임 오류가 발생합니다.
With Cache Components
섹션 제목: “With Cache Components”Cache Components를 사용할 때는 cookies, headers처럼 요청 데이터를 읽는 컴포넌트를 <Suspense>로 감싸야 페이지 나머지를 정적 셸로 사전 렌더링할 수 있습니다.
요청 데이터를 동적 컴포넌트에서 읽고 after에 전달하는 방식으로 이 패턴을 after와 결합할 수 있습니다:
app/page.tsx
JavaScriptTypeScript
import { Suspense } from 'react' import { after } from 'next/server' import { cookies } from 'next/headers' import { logUserAction } from '@/app/utils'
export default function Page() { return ( <> <h1>Part of the static shell</h1> <Suspense fallback={<p>Loading...</p>}> <DynamicContent /> </Suspense> </> ) }
async function DynamicContent() { const sessionCookie = (await cookies()).get('session-id')?.value || 'anonymous'
// Schedule work after the response is sent after(() => { logUserAction({ sessionCookie }) })
return <p>Your session: {sessionCookie}</p> }이 예시에서 <h1>과 <Suspense> 폴백은 정적 셸에 포함됩니다. DynamicContent는 렌더링 중 쿠키를 읽고 클로저를 통해 after에 전달합니다. cookies() 호출이 after 콜백 외부(컴포넌트 렌더링 시)에 있기 때문에 제대로 동작합니다.
Platform Support
섹션 제목: “Platform Support”| Deployment Option | Supported |
|---|---|
| Node.js server | Yes |
| Docker container | Yes |
| Static export | No |
| Adapters | Platform-specific |
Next.js를 셀프 호스팅할 때 after 구성 방법을 알아보세요.
Reference: serverless 플랫폼에서 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>()
// 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)) }Version History
섹션 제목: “Version History”| Version | Changes |
|---|---|
v15.1.0 | after가 안정화되었습니다. |
v15.0.0-rc | unstable_after가 도입되었습니다. |
Was this helpful?
supported.
Send