In the infrastructure of Metropolis Quantum 2150, where every operation must be optimized, you will learn about the
after() API - a function that lets you run code after the response has been sent to the user. It is the ideal solution for tasks such as logging, analytics, or cleanup.Imagine a typical scenario - a user visits a product page, and you want to:
Without
after(), all of these operations block the response:1// Bad approach - everything blocks the response
2export async function GET(request: Request) {
3 const product = await getProduct(id);
4
5 // These operations delay the response!
6 await logVisit(id);
7 await updateStats(id);
8 await sendAnalytics('product_view', { id });
9
10 return Response.json(product);
11}after() lets you schedule code to run AFTER the response is sent:1import { after } from 'next/server';
2
3export async function GET(request: Request) {
4 const product = await getProduct(id);
5
6 // Schedule execution after the response
7 after(async () => {
8 await logVisit(id);
9 await updateStats(id);
10 await sendAnalytics('product_view', { id });
11 });
12
13 // Response is sent immediately!
14 return Response.json(product);
15}after() requires enabling an experimental flag:1// next.config.js
2module.exports = {
3 experimental: {
4 after: true,
5 },
6};1// app/api/orders/route.ts
2import { after } from 'next/server';
3import { sendEmail, updateInventory, notifyWarehouse } from '@/lib/services';
4
5export async function POST(request: Request) {
6 const orderData = await request.json();
7
8 // Essential operation - create the order
9 const order = await createOrder(orderData);
10
11 // Side effects - run after the response
12 after(async () => {
13 // Confirmation email
14 await sendEmail({
15 to: orderData.email,
16 subject: 'Order confirmation',
17 template: 'order-confirmation',
18 data: order,
19 });
20
21 // Update inventory
22 await updateInventory(order.items);
23
24 // Notify the warehouse
25 await notifyWarehouse(order);
26
27 // Audit log
28 await auditLog('order_created', { orderId: order.id });
29 });
30
31 // Immediate response
32 return Response.json({
33 success: true,
34 orderId: order.id
35 });
36}1// app/products/[id]/page.tsx
2import { after } from 'next/server';
3import { trackPageView } from '@/lib/analytics';
4
5export default async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
6 const product = await getProduct((await params).id);
7
8 // Tracking after the page renders
9 after(async () => {
10 await trackPageView({
11 page: 'product',
12 productId: (await params).id,
13 productName: product.name,
14 category: product.category,
15 });
16 });
17
18 return (
19 <div className="product-page">
20 <h1>{product.name}</h1>
21 <p>{product.description}</p>
22 <span className="price">${product.price}</span>
23 </div>
24 );
25}1// app/actions/checkout.ts
2'use server';
3
4import { after } from 'next/server';
5import { revalidatePath } from 'next/cache';
6
7export async function completeCheckout(formData: FormData) {
8 const cartId = formData.get('cartId') as string;
9
10 // Essential operation
11 const order = await processPayment(cartId);
12
13 if (!order.success) {
14 return { error: 'Payment failed' };
15 }
16
17 // Revalidate paths
18 revalidatePath('/cart');
19 revalidatePath('/orders');
20
21 // Side effects after the response
22 after(async () => {
23 // Clear the cart in the background
24 await clearCart(cartId);
25
26 // Generate PDF invoice
27 await generateInvoice(order.id);
28
29 // External integrations
30 await syncWithERP(order);
31 await notifyShipping(order);
32
33 // Update the loyalty program
34 await updateLoyaltyPoints(order.userId, order.total);
35 });
36
37 return { success: true, orderId: order.id };
38}You can use
after() multiple times - all callbacks will run:1import { after } from 'next/server';
2
3export async function POST(request: Request) {
4 const data = await request.json();
5 const result = await processData(data);
6
7 // Logging
8 after(async () => {
9 await logger.info('Data processed', { id: result.id });
10 });
11
12 // Analytics
13 after(async () => {
14 await analytics.track('data_processed', {
15 processingTime: result.duration,
16 dataSize: data.length,
17 });
18 });
19
20 // Cleanup
21 after(async () => {
22 await cleanupTempFiles(result.tempPath);
23 });
24
25 return Response.json(result);
26}Errors inside
after() do not affect the response, but should be handled:1import { after } from 'next/server';
2
3export async function GET(request: Request) {
4 const data = await fetchData();
5
6 after(async () => {
7 try {
8 await riskyOperation();
9 } catch (error) {
10 // Log the error but do not interrupt
11 console.error('After callback failed:', error);
12 await errorReporting.capture(error);
13 }
14 });
15
16 return Response.json(data);
17}1// app/api/posts/[id]/like/route.ts
2import { after } from 'next/server';
3import { getSession } from '@/lib/auth';
4
5export async function POST(
6 request: Request,
7 { params }: { params: Promise<{ id: string }> }
8) {
9 const session = await getSession();
10 if (!session) {
11 return Response.json({ error: 'Unauthorized' }, { status: 401 });
12 }
13
14 // Essential operation - add the like
15 const like = await addLike((await params).id, session.userId);
16
17 // All notifications and side effects after the response
18 after(async () => {
19 const post = await getPost((await params).id);
20
21 // Notify the post author
22 if (post.authorId !== session.userId) {
23 await createNotification({
24 userId: post.authorId,
25 type: 'like',
26 message: `${session.user.name} liked your post`,
27 link: `/posts/${(await params).id}`,
28 });
29
30 // Push notification
31 await sendPushNotification(post.authorId, {
32 title: 'New like!',
33 body: `${session.user.name} liked your post`,
34 });
35 }
36
37 // Update statistics
38 await incrementPostStats((await params).id, 'likes');
39
40 // Update the feed algorithm
41 await updateFeedRanking((await params).id, 'engagement');
42 });
43
44 return Response.json({ liked: true, likeCount: like.count });
45}The
after() API in Next.js is a powerful optimization tool:In Metropolis Quantum 2150, where every millisecond matters,
after() lets your applications run at the speed of light while side effects quietly execute in the background!