How to Use NextRequest in Middleware in Next.js
In Next.js middleware, you use
NextRequest to access request details like headers, cookies, and URL. Import NextRequest from next/server and use it as the first argument in your middleware function to inspect or modify requests before they reach your routes.Syntax
The middleware function receives a NextRequest object that represents the incoming request. You can read properties like url, headers, and cookies. Return a NextResponse to modify the response or continue the request.
- NextRequest: Represents the HTTP request.
- NextResponse: Used to create or modify the response.
- middleware function: Runs on every request matching the configured matcher.
typescript
import { NextResponse, NextRequest } from 'next/server'; export function middleware(request: NextRequest) { // Access request properties const url = request.nextUrl.clone(); // Example: Redirect if path is /old if (url.pathname === '/old') { url.pathname = '/new'; return NextResponse.redirect(url); } // Continue without changes return NextResponse.next(); }
Example
This example middleware checks if the user is visiting the /dashboard path. If the user is not authenticated (no token cookie), it redirects them to /login. Otherwise, it allows the request to continue.
typescript
import { NextResponse, NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const { pathname } = request.nextUrl; const token = request.cookies.get('token'); if (pathname.startsWith('/dashboard')) { if (!token) { const loginUrl = new URL('/login', request.url); return NextResponse.redirect(loginUrl); } } return NextResponse.next(); }
Output
When visiting /dashboard without a 'token' cookie, the user is redirected to /login. Otherwise, the request proceeds normally.
Common Pitfalls
- Not importing
NextRequestandNextResponsefromnext/server. - Trying to mutate
request.nextUrldirectly instead of cloning it before changes. - Forgetting to return
NextResponse.next()to continue the request. - Using middleware for heavy logic causing performance issues.
typescript
import { NextResponse, NextRequest } from 'next/server'; // Wrong: Mutating nextUrl directly export function middleware(request: NextRequest) { if (request.nextUrl.pathname === '/old') { // request.nextUrl.pathname = '/new'; // This is not allowed const url = request.nextUrl.clone(); url.pathname = '/new'; return NextResponse.redirect(url); } return NextResponse.next(); } // Right: Clone nextUrl before modifying export function middleware(request: NextRequest) { const url = request.nextUrl.clone(); if (url.pathname === '/old') { url.pathname = '/new'; return NextResponse.redirect(url); } return NextResponse.next(); }
Quick Reference
| Feature | Description | Example |
|---|---|---|
| Access URL | Use request.nextUrl to get the URL object | const url = request.nextUrl; |
| Read Cookies | Use request.cookies.get('name') to read cookies | const token = request.cookies.get('token'); |
| Redirect | Return NextResponse.redirect(url) to redirect | return NextResponse.redirect(new URL('/login', request.url)); |
| Continue Request | Return NextResponse.next() to continue | return NextResponse.next(); |
| Modify URL | Clone nextUrl before changing | const url = request.nextUrl.clone(); url.pathname = '/new'; |
Key Takeaways
Import NextRequest and NextResponse from next/server to use in middleware.
Use NextRequest to read request details like URL, headers, and cookies.
Clone request.nextUrl before modifying it to avoid errors.
Return NextResponse.next() to continue or NextResponse.redirect() to redirect.
Middleware runs before routes and can control request flow efficiently.