What is Middleware?
- Middleware is like a helper that runs before your web server finishes handling a request.
- It can modify the request or response, such as changing data, changing where the request goes, or modifying how things look.
- Middleware runs before the server looks for cached content or matches the request to a specific route (URL pattern).
- So, it acts as a pre-processing step that can shape how requests and responses are handled.
Key Functions of Middleware
- Modify Requests: Change or add data to the request before it reaches the server.
- Alter Responses: Adjust or append data to the response before it is returned to the user.
- Redirect or Rewrite: Control where the user ends up or how the request is handled without changing the URL in the browser.
Convention Section
- Convention means there’s a standard way to do things.
- To define a file named ‘middleware.js’ or ‘middleware.ts’.
- Place this file in the root of your project.
//Path: src/middleware.ts or //Path:Â src/middleware.js
Let’s look at an example:
//Path:Â src/middleware.ts import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { return NextResponse.redirect(new URL('/', request.url)) } export const config = { matcher: '/about/:path*', }
This Next.js middleware redirects any request to paths starting with /about to the root of the site (‘/’). The matcher setting ensures it applies to /about and all its sub-paths, like /about/team, effectively sending users from any /about page to the homepage.
You can also:
- Add custom headers easily.
- Send a JSON response based on specific conditions, such as indicating a database issue if the database is down.
To access the request object, export a ‘config’ object with a ‘matcher’ key to specify which paths the midmiddlewareould handle.
Conditional Statements
Use if-else conditions to implement complex logic. For instance, redirect or rewrite based on different URL patterns or request attributes.
- Another approach is to use conditional statements with if-else conditions.
- Instead of specifying paths to match, you can use these conditions to implement more complex logic.
- For example, if a path starts with /about (http://localhost:3000/about), you can rewrite it to the ‘/’ page ( http://localhost:3000).
Redirects vs. Rewrites
In middleware, it is essential to understand the difference between redirects and rewrites:
Redirect: Redirects send the user’s browser to a different URL. The browser updates the address bar to show the new URL, and the user sees the content from that new URL.
Rewrites: Rewrites serve content from a different URL while keeping the original URL in the address bar. The browser’s address bar does not change, but the content displayed is from the rewritten URL.
The NextResponse API allows you to:
- Redirect the incoming request to a different URL.
- Rewrite the response by serving content from a different URL while keeping the original URL in the address bar.
Let’s understand this with an example:
Redirect Example:
//Path:Â src/middleware.ts import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { if (request.nextUrl.pathname.startsWith('/about')) { return NextResponse.redirect(new URL('/', request.url)) } if (request.nextUrl.pathname.startsWith('/login')) { return NextResponse.rewrite(new URL('/', request.url)) } }
- If you use the redirect function for the /about page and you’re on the URL http://localhost:3000/about, refreshing the page will redirect you to the / page.
- The address bar will update to http://localhost:3000.
- Consequently, you will see the content from the / page at http://localhost:3000.
Output:
Rewrite Example:
//Path: src/middleware.ts 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('/', request.url)) } if (request.nextUrl.pathname.startsWith('/login')) { return NextResponse.rewrite(new URL('/', request.url)) } }
Â
- If you use the rewrite function to handle requests to /about, but it shows the data from the / page while keeping the URL as http://localhost:3000/about, the middleware’s content from /, but the URL remains /about.
- The same behavior will occur for the Login page if a similar logic is applied.
Output:
Matcher Configuration
The matcher configuration allows you to specify which paths the middleware should apply to.
In middleware.js:
To match a single path, you can configure it like this:
//Path:Â src/middleware.ts export const config = { matcher: '/about/:path*', }
To match multiple paths, you can use an array syntax:
//Path:Â src/middleware.ts export const config = { matcher: ['/about/:path*', '/login/:path*'], }
This configuration helps filter, which requests the middleware process based on the specified paths.
Conclusion
Middleware customizes how your web app handles requests and responses. It lets you modify, redirect, or manage requests before they reach your server. Set it up in ‘middleware.js’ or ‘middleware.ts’ to enhance your app’s behavior with tailored logic and routing.
Source: Read MoreÂ