NextJs / Routes / Middleware
Middleware
-
1. Files
1, Basic code
Create middleware.ts in the project root folder
Example 1import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware (request: NextRequest) { return NextResponse.next() } Apply middlewre to the routes started with 'about'
Example 2import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' // This function can be marked `async` if using `await` inside export function middleware(request: NextRequest) { return NextResponse.redirect(new URL('/home', request.url)) } // See "Matching Paths" below to learn more export const config = { matcher: '/about/:path*', } Multiple route mactcher
Example 3export const config = { matcher: ['/about/:path*', '/dashboard/:path*'], } except specific paths
Example 3export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - api (API routes) * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) */ '/((?!api|_next/static|_next/image|favicon.ico).*)', ], } Conditional Statements
import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { if (request.nextUrl.pathname.startsWith('/about')) { return NextResponse.rewrite(new URL('/about-2', request.url)) } if (request.nextUrl.pathname.startsWith('/dashboard')) { return NextResponse.rewrite(new URL('/dashboard/user', request.url)) } } 2. Multiple Routes
3. Implement route protection
BeforeWe can direct access the routes now
1. add matcher
2. Restrict the user's routesimport { NextRequest, NextResponse } from 'next/server'; export async function middleware(req: NextRequest) { return NextResponse.next(); } export const config = { matcher: ['/api/users/:path*', '/api/admin/:path*'] }; npm install lodash
3. Restrict the admin routesimport { NextRequest, NextResponse } from 'next/server'; import { includes } from "lodash"; const isUserRoute = (pathname: string) => { return pathname.startsWith('/api/users'); } export async function middleware(req: NextRequest) { const role = req.headers.get("authorization"); const { pathname } = req.nextUrl; if (isUserRoute(pathname) && !includes(["user", "admin"], role)) { return NextResponse.redirect(new URL('/api/auth/unauthorized', req.url)); } return NextResponse.next(); } export const config = { matcher: ['/api/users/:path*', '/api/admin/:path*'] };
Afterimport { NextRequest, NextResponse } from 'next/server'; import { includes } from "lodash"; const isAdminRoute = (pathname: string) => { return pathname.startsWith('/api/admin'); } const isUserRoute = (pathname: string) => { return pathname.startsWith('/api/users'); } export async function middleware(req: NextRequest) { const role = req.headers.get("authorization"); const { pathname } = req.nextUrl; if (isUserRoute(pathname) && !includes(["user", "admin"], role)) { return NextResponse.redirect(new URL('/api/auth/unauthorized', req.url)); } if (isAdminRoute(pathname) && role !== "admin") { return NextResponse.redirect(new URL('/api/auth/unauthorized', req.url)); } return NextResponse.next(); } export const config = { matcher: ['/api/users/:path*', '/api/admin/:path*'] };