Back to Blog
Lesson 34 of the Next.js: Build Full-Stack Apps with the App Router course
Next.jsAugust 21, 20264 min read

Middleware Basics: Intercepting Requests in Next.js

Learn how to use Next.js middleware to intercept requests, perform server-side redirects, and control user access before your application fully loads.

Next.jsMiddlewareRoutingServer-SideWeb Development

Previously in this course, we covered deploying to Vercel, which finalized our production setup. This lesson adds a new capability: the ability to run code before a request is completed, effectively intercepting the user's path through your application.

Understanding Middleware from First Principles

In a typical request cycle, a user clicks a link, and Next.js renders the corresponding page. Middleware allows you to inject logic into that cycle. It executes on the server before a request is processed by your route segments.

Think of middleware as a security guard or a gatekeeper standing in front of your application. Because it runs before the route is rendered, it is the ideal place for:

  • Redirects: Sending a user from an old URL to a new one.
  • Authentication: Checking if a user has a session token before allowing them to see a private page.
  • Rewrites: Masking URLs or performing A/B testing.

Creating Your middleware.ts File

To start using this feature, create a file named middleware.ts at the root of your project directory (at the same level as your app folder). Next.js will automatically detect this file and apply the logic within it to your entire application.

Here is a basic example of how to intercept a request and perform a redirect:

TYPESCRIPT
import { NextResponse } from CE9178">'next/server';
import type { NextRequest } from CE9178">'next/server';

export function middleware(request: NextRequest) {
  // Check if the user is trying to access the /admin path
  if (request.nextUrl.pathname.startsWith(CE9178">'/admin')) {
    // Redirect them to the login page instead
    return NextResponse.redirect(new URL(CE9178">'/login', request.url));
  }

  // Otherwise, let the request proceed normally
  return NextResponse.next();
}

// Optional: Use a matcher to run middleware only on specific paths
export const config = {
  matcher: [CE9178">'/admin/:path*'],
};

How the Request Lifecycle Works

When a request enters your application, the middleware.ts file is the first point of contact.

  1. Request Initiation: A user requests a URL.
  2. Middleware Execution: The code in middleware.ts runs.
  3. Decision:
    • If you return NextResponse.redirect(), the request is halted and sent elsewhere.
    • If you return NextResponse.next(), the request proceeds to your app folder to render the page.

For more advanced security patterns, you can see how this integrates with Next.js Policy-Based Access Control: Middleware & Server Action Decorators to manage permissions at scale.

Hands-on Exercise: Redirecting Legacy Paths

Suppose you recently renamed your "About Us" page from /about-old to /about. To ensure your users don't hit a 404, you want to redirect them automatically.

  1. Open your middleware.ts file.
  2. Add a condition to check if request.nextUrl.pathname equals /about-old.
  3. Use NextResponse.redirect() to point the user to /about.
  4. Test the redirect by navigating to your local server at http://localhost:3000/about-old.

Common Pitfalls

  • Forgetting the Matcher: Without a matcher config, your middleware runs on every request, including static assets (like images or CSS). This can drastically slow down your site. Always limit your middleware to the routes that actually need it.
  • Infinite Redirects: Be careful not to redirect a page to itself (e.g., redirecting /login to /login). This causes an infinite loop that will crash the browser.
  • Heavy Logic: Because middleware runs on every request, keep it lightweight. Do not perform complex database queries here. If you need to check a database, consider Next.js Rate Limiting: Secure Server Actions and Middleware Patterns to understand how to handle such tasks efficiently.

FAQ

Can I use React hooks in middleware? No. Middleware runs in a restricted runtime environment on the server and does not have access to React or DOM APIs.

Does middleware replace API routes? No. Middleware is for cross-cutting concerns like redirects and headers, while API routes (or Route Handlers) are for business logic and data manipulation.

Can I set cookies in middleware? Yes. You can add or modify cookies on the NextResponse object before returning it, which is useful for setting session identifiers.

Recap

Middleware provides a powerful way to intercept requests at the edge. By using middleware.ts, you can enforce redirects and protect routes globally. Always use a matcher to optimize performance and avoid unnecessary executions.

Up next: We will dive into Implementing Dark Mode to give your blog a modern, user-friendly aesthetic.

Similar Posts