What if you could protect your whole site with just one simple check?
Why Protected routes with middleware in NextJS? - Purpose & Use Cases
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine you have a website where some pages should only be seen by logged-in users. You try to check if a user is logged in on every page manually by adding code everywhere.
Manually checking login status on every page is tiring and easy to forget. If you miss one page, anyone can see it. It also makes your code messy and hard to update.
Using middleware for protected routes lets you write the login check once. Middleware runs before your pages load and blocks access if the user is not logged in, keeping your code clean and secure.
if (!user) { redirect('/login') } // on every page
import { NextResponse } from 'next/server'; export function middleware(req) { if (!req.cookies.get('token')) { return NextResponse.redirect(new URL('/login', req.url)); } }
This lets you protect many pages easily and keep your app safe without repeating code everywhere.
Think of a gym where only members can enter certain rooms. Middleware is like a guard checking membership at the door, so you don't need a guard inside every room.
Manual checks on every page are slow and error-prone.
Middleware runs once before pages load to protect routes.
This keeps your app secure and your code simple.
Practice
Solution
Step 1: Understand middleware role
Middleware runs before a page loads to control access or modify requests.Step 2: Identify protection purpose
In protected routes, middleware checks if a user is authenticated before allowing access.Final Answer:
To check user authentication before allowing access to certain pages -> Option AQuick Check:
Middleware protects routes by checking authentication [OK]
- Thinking middleware styles pages
- Confusing middleware with database management
- Assuming middleware preloads images
Solution
Step 1: Recall Next.js middleware export syntax
Middleware must be exported as the default export function named middleware.Step 2: Check options for correct syntax
Only export default function middleware(req) { /* code */ } uses "export default function middleware(req)" which is valid syntax.Final Answer:
export default function middleware(req) { /* code */ } -> Option DQuick Check:
Middleware uses default export function [OK]
- Using named export instead of default
- Assigning middleware to a variable without export default
- Incorrect export statement syntax
import { NextResponse } from 'next/server';
export default function middleware(req) {
const token = req.cookies.get('token');
if (!token) {
return NextResponse.redirect(new URL('/login', req.url));
}
return NextResponse.next();
}Solution
Step 1: Analyze token check in middleware
The middleware checks if the 'token' cookie exists; if not, it triggers a redirect.Step 2: Understand redirect behavior
If no token, middleware returns a redirect response to '/login' page.Final Answer:
The user is redirected to the /login page -> Option BQuick Check:
No token causes redirect to login [OK]
- Assuming user stays on page without token
- Thinking middleware throws error on missing token
- Confusing redirect target URL
import { NextResponse } from 'next/server';
export default function middleware(req) {
const token = req.cookies.token;
if (!token) {
return NextResponse.redirect('/login');
}
return NextResponse.next();
}Solution
Step 1: Check cookie access method
In Next.js middleware, cookies are accessed with req.cookies.get('token'), not req.cookies.token.Step 2: Verify redirect usage
Redirect can accept a relative path, so that is valid here.Final Answer:
Accessing cookies incorrectly; should use req.cookies.get('token') -> Option CQuick Check:
Use req.cookies.get('token') to read cookies [OK]
- Using dot notation for cookies object
- Thinking redirect URL must be absolute
- Confusing NextResponse.next() with continue()
/dashboard using middleware. Which is the correct way to apply middleware only to these routes?Solution
Step 1: Understand matcher pattern syntax
The matcher uses path patterns where ':path*' matches all subpaths under /dashboard.Step 2: Compare options for correct pattern
export const config = { matcher: ['/dashboard/:path*'] }; uses '/dashboard/:path*' which correctly matches /dashboard and all nested routes.Final Answer:
export const config = { matcher: ['/dashboard/:path*'] }; -> Option AQuick Check:
Use '/dashboard/:path*' to match dashboard and subpaths [OK]
- Using wildcard * without colon for subpaths
- Matching only exact /dashboard without subpaths
- Using invalid glob pattern like /**
