To receive event notifications from external services like a CMS, use a Route Handler. The following example listens on /app/webhook/route.ts:
export async function GET(request: NextRequest) {
const token = request.nextUrl.searchParams.get('token')
if (token !== process.env.REVALIDATE_SECRET_TOKEN) {
return NextResponse.json({ success: false }, { status: 401 })
}
const tag = request.nextUrl.searchParams.get('tag')
if (!tag) {
return NextResponse.json({ success: false }, { status: 400 })
}
revalidateTag(tag)
return NextResponse.json({ success: true })
}After completing a third-party flow, users are redirected to a callback URL. You can use this to set a session cookie and redirect the user:
export async function GET(request: NextRequest) {
const token = request.nextUrl.searchParams.get('session_token')
const redirectUrl = request.nextUrl.searchParams.get('redirect_url')
const response = NextResponse.redirect(new URL(redirectUrl, request.url))
response.cookies.set({
value: token,
name: '_token',
path: '/',
secure: true,
httpOnly: true,
})
return response
}The proxy.ts file can intercept requests before they reach their destination. Only one proxy file is allowed per project.
export const config = {
matcher: '/api/:function*',
}
export function proxy(request: Request) {
if (!isAuthenticated(request)) {
return Response.json({ success: false, message: 'authentication failed' }, { status: 401 })
}
}Other examples include:
NextResponse.rewrite()NextResponse.redirect()Never pass incoming request headers directly to the response. Response headers are visible to clients.
export async function POST(request: Request) {
const { rateLimited } = await checkRateLimit(request)
if (rateLimited) {
return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 })
}
return new Response(null, { status: 204 })
}OPTIONS requests ask the server if a request is allowed. If not defined, Next.js adds it automatically and sets the Allow header.
Some libraries use a factory pattern to generate handlers:
import { createHandler } from 'third-party-library'
const handler = createHandler({ /* options */ })
export const GET = handler
export { handler as POST }dynamic = 'force-static' are supportedNext.js provides powerful tools for receiving events, managing sessions, proxying requests, and securing your backend. With Route Handlers, proxy logic, and careful request validation, you can build a robust and secure integration layer for third-party services.