What if your app could instantly know when something important happens without asking all the time?
Why Route handlers for webhooks in NextJS? - Purpose & Use Cases
Imagine you want your website to react instantly when a payment is made or a form is submitted on another service. You try to check for these events by constantly asking the other service if something new happened.
Manually checking for updates means your site is always busy asking questions, wasting resources and slowing down. Plus, you might miss important events or get delayed responses, making your app unreliable.
Route handlers for webhooks let your site listen quietly and wait for the other service to send a message only when something important happens. This way, your app reacts instantly and efficiently without wasting effort.
setInterval(() => fetch('https://api.service.com/events'), 5000);
export async function POST(request) { /* handle webhook event here */ }This makes your app instantly responsive to real-world events, improving user experience and saving server resources.
When a customer completes a payment on Stripe, Stripe sends a webhook to your route handler, which updates the order status immediately without delay.
Manual polling wastes resources and can miss events.
Route handlers wait for real-time messages from other services.
This creates fast, reliable, and efficient app reactions.
Practice
Solution
Step 1: Understand webhook data sending
Webhooks send data to your server, usually using the POST method to submit event payloads.Step 2: Match HTTP method in Next.js route handler
To receive webhook data, your Next.js route handler must listen for POST requests.Final Answer:
POST -> Option BQuick Check:
Webhook data uses POST = POST [OK]
- Using GET method which does not carry webhook payload
- Using PUT or DELETE which are not standard for webhooks
- Not specifying method and allowing all methods
Solution
Step 1: Identify Next.js route handler syntax
Next.js route handlers export named functions matching HTTP methods, e.g., export function POST(req) { ... }Step 2: Check each option for correct syntax
export function POST(req) { return new Response('ok') } uses correct named export POST with a Request object and returns a Response. Others use Express style or wrong method names.Final Answer:
export function POST(req) { return new Response('ok') } -> Option AQuick Check:
Named export POST with Request and Response = export function POST(req) { return new Response('ok') } [OK]
- Using default export instead of named export for POST
- Using lowercase 'post' instead of uppercase 'POST'
- Mixing Express.js syntax with Next.js route handlers
export async function POST(req) {
const data = await req.json();
if (data.event === 'ping') {
return new Response('pong', { status: 200 });
}
return new Response('ignored', { status: 204 });
}Solution
Step 1: Analyze conditional response
If the JSON body has event equal to 'ping', the handler returns status 200 with 'pong'. Otherwise, it returns status 204 with 'ignored'.Step 2: Understand status codes
Status 200 means OK, 204 means No Content (successful but no response body expected). The code matches these conditions exactly.Final Answer:
200 if event is 'ping', otherwise 204 -> Option CQuick Check:
Conditional status 200 or 204 = 200 if event is 'ping', otherwise 204 [OK]
- Assuming always 200 regardless of condition
- Confusing 204 with error status
- Ignoring async/await for JSON parsing
export async function POST(req) {
const body = await req.json;
return new Response('Received');
}Solution
Step 1: Check usage of req.json
req.json is a function and must be called with parentheses: req.json()Step 2: Verify other parts
Returning new Response with plain text is valid; async function is allowed. So only missing parentheses is error.Final Answer:
Missing parentheses when calling req.json() -> Option DQuick Check:
req.json() requires parentheses = Missing parentheses when calling req.json() [OK]
- Forgetting parentheses on req.json causing runtime error
- Assuming POST must be synchronous
- Thinking Response must be JSON always
Solution
Step 1: Check method and header access
Webhook must use POST method and access headers with req.headers.get('header-name'). export async function POST(req) { const token = req.headers.get('x-secret-token'); if (token !== 'mysecret') { return new Response('Unauthorized', { status: 401 }); } return new Response('Webhook received', { status: 200 }); } uses POST and correct header name 'x-secret-token'.Step 2: Verify authorization logic and response
If token mismatches, respond 401 Unauthorized; else respond 200 OK. export async function POST(req) { const token = req.headers.get('x-secret-token'); if (token !== 'mysecret') { return new Response('Unauthorized', { status: 401 }); } return new Response('Webhook received', { status: 200 }); } correctly implements this logic.Final Answer:
Option A code snippet -> Option AQuick Check:
POST + req.headers.get + 401 on bad token = export async function POST(req) { const token = req.headers.get('x-secret-token'); if (token !== 'mysecret') { return new Response('Unauthorized', { status: 401 }); } return new Response('Webhook received', { status: 200 }); } [OK]
- Using GET instead of POST for webhook
- Accessing headers as object instead of using .get()
- Reversing authorization logic (401 on valid token)
- Using Express style req, res in Next.js route handlers
Ready to prove it?
Pass the test and this pattern moves unknown
