Bird
Raised Fist0
NextJSframework~15 mins

Why middleware intercepts requests in NextJS - Why It Works This Way

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Overview - Why middleware intercepts requests
What is it?
Middleware in Next.js is a special code that runs before a request reaches your page or API route. It can look at the request, change it, or decide what happens next. This lets you control things like authentication, redirects, or adding headers before the main code runs.
Why it matters
Without middleware, every page or API would need to repeat the same checks or changes, making your app slower and harder to maintain. Middleware helps keep your app organized and efficient by handling common tasks in one place before the request moves on.
Where it fits
You should understand basic Next.js routing and API routes before learning middleware. After this, you can explore advanced topics like edge functions, server components, and custom headers to build faster, smarter apps.
Mental Model
Core Idea
Middleware acts like a gatekeeper that checks and can change requests before they reach your app’s main code.
Think of it like...
Middleware is like a security guard at a building entrance who checks IDs, redirects visitors, or adds passes before letting them inside.
┌─────────────┐
│ Incoming    │
│ Request     │
└─────┬───────┘
      │
┌─────▼───────┐
│ Middleware  │
│ (Intercept) │
└─────┬───────┘
      │
┌─────▼───────┐
│ Main App    │
│ (Page/API)  │
└─────────────┘
Build-Up - 6 Steps
1
FoundationWhat is Middleware in Next.js
🤔
Concept: Middleware is code that runs before your app handles a request.
In Next.js, middleware is a special function placed in the middleware.js file or middleware.ts file at the root or inside the app directory. It runs on every request to your app and can inspect or modify the request or response.
Result
You get a chance to run code before any page or API route runs.
Understanding middleware as a first step helps you see how you can control requests globally without changing each page.
2
FoundationHow Middleware Intercepts Requests
🤔
Concept: Middleware runs automatically on requests before your app’s main code.
When a user visits your site, Next.js sends the request to middleware first. Middleware can then decide to continue to the page, redirect, rewrite, or respond immediately.
Result
Requests are paused at middleware, giving you control over what happens next.
Knowing that middleware runs first explains why it can change the flow of requests.
3
IntermediateCommon Uses of Middleware Interception
🤔Before reading on: do you think middleware can only block requests or can it also modify them? Commit to your answer.
Concept: Middleware can do many things like authentication, redirects, and adding headers.
Middleware often checks if a user is logged in, redirects them if not, or adds security headers. It can also rewrite URLs or respond with custom messages without reaching the main app code.
Result
Your app can protect pages, improve security, and customize behavior efficiently.
Understanding middleware’s flexibility shows why it’s a powerful tool for common app needs.
4
IntermediateMiddleware Runs on the Edge
🤔Before reading on: do you think middleware runs on your server or closer to the user? Commit to your answer.
Concept: Next.js middleware runs at the edge, near the user, for faster response.
Middleware runs on edge servers worldwide, not just your main server. This means it can handle requests quickly by running close to users, reducing delays.
Result
Your app feels faster because middleware handles requests near users before reaching your server.
Knowing middleware runs on the edge explains its speed advantage and why it’s good for global apps.
5
AdvancedHow Middleware Affects Request Flow
🤔Before reading on: do you think middleware can stop a request from reaching the page? Commit to your answer.
Concept: Middleware can stop, redirect, rewrite, or let requests pass through to pages or APIs.
Middleware returns special responses like NextResponse.redirect() to send users elsewhere, NextResponse.rewrite() to change the URL internally, or NextResponse.next() to continue. This controls exactly what the user sees and when.
Result
Requests can be fully controlled, improving security and user experience.
Understanding these controls helps you design precise request handling and avoid bugs.
6
ExpertMiddleware Limitations and Performance Impact
🤔Before reading on: do you think adding middleware always makes your app faster? Commit to your answer.
Concept: Middleware adds power but can slow requests if overused or misused.
Because middleware runs on every matching request, heavy or complex logic can slow down your app. Also, middleware can’t access certain APIs like Node.js file system or database directly. Knowing these limits helps you write efficient middleware.
Result
You balance middleware use for speed and functionality.
Knowing middleware’s limits prevents performance problems and guides better architecture.
Under the Hood
Next.js middleware runs as a lightweight function on edge servers using the Web Fetch API. It intercepts HTTP requests before they reach your app’s routing layer. Middleware receives a Request object, can inspect or modify it, and returns a Response or passes control forward. This happens in a sandboxed environment without full Node.js APIs, optimized for speed and security.
Why designed this way?
Middleware was designed to run on the edge to reduce latency by handling requests closer to users. Running middleware before routing allows centralized control of requests, avoiding repeated code in pages. The sandboxed environment ensures security and fast cold starts, trading off some Node.js features for performance.
┌───────────────┐
│ User Request  │
└──────┬────────┘
       │
┌──────▼────────┐
│ Edge Middleware│
│ (Inspect/Modify│
│  Request)     │
└──────┬────────┘
       │
┌──────▼────────┐
│ Next.js Router│
│ (Page/API)    │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does middleware run after your page code or before? Commit to your answer.
Common Belief:Middleware runs after the page code to fix things if needed.
Tap to reveal reality
Reality:Middleware runs before the page code to control or change requests early.
Why it matters:Thinking middleware runs after pages leads to wrong assumptions about request flow and bugs in access control.
Quick: Can middleware access your database directly? Commit to your answer.
Common Belief:Middleware can use any Node.js API, including databases.
Tap to reveal reality
Reality:Middleware runs in a restricted edge environment without full Node.js APIs, so it cannot access databases directly.
Why it matters:Trying to use unsupported APIs in middleware causes runtime errors and confusion.
Quick: Does adding middleware always speed up your app? Commit to your answer.
Common Belief:Middleware always makes apps faster by handling requests early.
Tap to reveal reality
Reality:Middleware can add delay if it runs heavy logic or is misused, slowing down requests.
Why it matters:Ignoring middleware’s performance cost can degrade user experience.
Quick: Does middleware only block requests or can it also rewrite URLs? Commit to your answer.
Common Belief:Middleware can only block or redirect requests, not rewrite URLs.
Tap to reveal reality
Reality:Middleware can rewrite URLs internally, changing the request path without redirecting the user.
Why it matters:Missing this feature limits creative routing and optimization strategies.
Expert Zone
1
Middleware runs before Next.js routing but after some network layers, so headers like cookies are available but some request details may be limited.
2
Middleware’s edge environment restricts certain Node.js features, so you must design logic to work with Web APIs and avoid server-only code.
3
Middleware can be composed by chaining multiple middleware files or functions, but order matters and can cause subtle bugs if misunderstood.
When NOT to use
Avoid middleware for heavy data processing, database queries, or tasks needing full Node.js APIs. Use API routes or server-side functions instead. Also, don’t use middleware for client-side UI logic or state management.
Production Patterns
In production, middleware is used for authentication checks, A/B testing redirects, locale detection, security headers, and caching strategies. Teams often centralize access control in middleware to keep pages clean and consistent.
Connections
HTTP Interceptors
Middleware is a type of HTTP interceptor that modifies requests and responses.
Understanding middleware as an interceptor helps grasp its role in controlling network traffic before main processing.
Operating System Kernel Hooks
Middleware intercepts requests like kernel hooks intercept system calls before they reach the OS core.
Knowing this connection reveals middleware’s role as a control layer that can allow, modify, or block actions early.
Airport Security Checkpoints
Middleware functions like security checkpoints that screen passengers before boarding.
This cross-domain link shows how early inspection improves safety and flow, just like middleware improves app security and performance.
Common Pitfalls
#1Trying to use Node.js APIs like fs or database clients inside middleware.
Wrong approach:import fs from 'fs'; export function middleware(request) { const data = fs.readFileSync('/data.txt'); return NextResponse.next(); }
Correct approach:export function middleware(request) { // Use only Web APIs or fetch for data return NextResponse.next(); }
Root cause:Misunderstanding that middleware runs in a restricted edge environment without full Node.js support.
#2Running heavy or slow code inside middleware causing delays.
Wrong approach:export async function middleware(request) { await new Promise(resolve => setTimeout(resolve, 5000)); return NextResponse.next(); }
Correct approach:export function middleware(request) { // Keep logic fast and simple return NextResponse.next(); }
Root cause:Not realizing middleware runs on every request and must be optimized for speed.
#3Assuming middleware runs after page code and placing logic accordingly.
Wrong approach:export function middleware(request) { // Trying to fix page errors here return NextResponse.next(); } // But page code runs before middleware
Correct approach:export function middleware(request) { // Middleware runs before page code return NextResponse.next(); }
Root cause:Confusing request lifecycle order in Next.js.
Key Takeaways
Middleware in Next.js runs before your app’s main code to intercept and control requests early.
It acts like a gatekeeper, allowing you to add authentication, redirects, or modify requests globally.
Middleware runs on edge servers for speed but has limits like no full Node.js API access.
Using middleware wisely improves app security, performance, and maintainability by centralizing common logic.
Misusing middleware can cause performance issues or runtime errors, so understanding its environment and flow is crucial.

Practice

(1/5)
1. What is the main reason Next.js middleware intercepts requests?
easy
A. To render React components on the server
B. To directly update the database
C. To check or modify requests before they reach the app
D. To compile CSS styles

Solution

  1. Step 1: Understand middleware role

    Middleware runs before the app processes requests, allowing inspection or modification.
  2. Step 2: Identify middleware purpose

    It is used for tasks like login checks, redirects, or adding headers before the app handles the request.
  3. Final Answer:

    To check or modify requests before they reach the app -> Option C
  4. Quick Check:

    Middleware intercepts requests = B [OK]
Hint: Middleware runs before app handles requests [OK]
Common Mistakes:
  • Thinking middleware renders UI components
  • Assuming middleware updates databases directly
  • Confusing middleware with CSS compilation
2. Which of the following is the correct way to continue request processing in Next.js middleware?
easy
A. return NextResponse.next()
B. return fetch()
C. return res.send()
D. return render()

Solution

  1. Step 1: Identify continuation method

    Next.js middleware uses NextResponse.next() to continue processing the request.
  2. Step 2: Eliminate incorrect options

    fetch() is for network calls, res.send() is Express.js syntax, render() is unrelated here.
  3. Final Answer:

    return NextResponse.next() -> Option A
  4. Quick Check:

    Continue middleware with NextResponse.next() = D [OK]
Hint: Use NextResponse.next() to continue middleware [OK]
Common Mistakes:
  • Using Express.js methods like res.send()
  • Trying to fetch inside middleware to continue
  • Calling render() which is not middleware syntax
3. Given this middleware code snippet, what happens when a request to '/dashboard' is made?
import { NextResponse } from 'next/server';
export function middleware(request) {
  if (!request.cookies.get('token')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}
medium
A. The user is redirected to '/login' if no token cookie is found
B. The request is blocked with an error
C. The request proceeds without any check
D. The middleware crashes due to syntax error

Solution

  1. Step 1: Analyze cookie check

    The middleware checks if the 'token' cookie exists in the request.
  2. Step 2: Determine behavior based on cookie

    If no token cookie, it redirects to '/login'; otherwise, it continues processing.
  3. Final Answer:

    The user is redirected to '/login' if no token cookie is found -> Option A
  4. Quick Check:

    Missing token cookie triggers redirect = A [OK]
Hint: Check cookie presence to decide redirect or continue [OK]
Common Mistakes:
  • Assuming request is blocked instead of redirected
  • Thinking middleware crashes due to syntax
  • Ignoring cookie check and assuming request proceeds
4. Identify the error in this Next.js middleware code:
import { NextResponse } from 'next/server';
export function middleware(request) {
  if (request.nextUrl.pathname === '/admin') {
    NextResponse.redirect('/login');
  }
  return NextResponse.next();
}
medium
A. Incorrect import statement for NextResponse
B. Missing return before NextResponse.redirect()
C. Using request.nextUrl.pathname instead of request.url
D. NextResponse.next() should not be called

Solution

  1. Step 1: Check redirect usage

    NextResponse.redirect() must be returned to stop further processing.
  2. Step 2: Identify missing return

    The code calls NextResponse.redirect() but does not return it, so middleware continues incorrectly.
  3. Final Answer:

    Missing return before NextResponse.redirect() -> Option B
  4. Quick Check:

    Always return redirect response in middleware = A [OK]
Hint: Always return redirect response in middleware [OK]
Common Mistakes:
  • Forgetting to return redirect response
  • Confusing request.nextUrl with request.url
  • Thinking NextResponse.next() is disallowed
5. You want to use Next.js middleware to block access to '/secret' unless a user has a valid 'auth' cookie. Which approach correctly applies this logic and continues processing other requests normally?
hard
A. Throw an error if 'auth' cookie is missing
B. Always return NextResponse.next() without checking cookies
C. Modify the request URL directly without returning a response
D. Return NextResponse.redirect('/login') if no 'auth' cookie; else return NextResponse.next()

Solution

  1. Step 1: Define blocking condition

    Check if the 'auth' cookie exists when the request is for '/secret'.
  2. Step 2: Apply redirect or continue

    If no cookie, return a redirect response to '/login'; otherwise, call NextResponse.next() to continue.
  3. Final Answer:

    Return NextResponse.redirect('/login') if no 'auth' cookie; else return NextResponse.next() -> Option D
  4. Quick Check:

    Redirect missing auth, else continue = C [OK]
Hint: Redirect missing auth cookie, else continue with NextResponse.next() [OK]
Common Mistakes:
  • Not returning redirect response
  • Throwing errors instead of redirecting
  • Modifying request without returning response