Motivation
I’m working with Next.js project for a few years now, after Vercel moved multiple /**/_middleware.ts files to a single /middleware.ts file, there was a unfilled gap - but just for now. After a 2023 retro I had found that there is no good solution for that problem, so I took matters into my own hands. I wanted to share that motivation with everyone here, as I think that we all need to remember how it all started.
Hope it will save you some time and would make your project DX better!
The problem
By default Next.js supports only one middleware.ts file, in which you need match routes with logic by your own which can be pretty problematic and chaotic. Also it’s endlessly making middleware boilerplate bigger.
// example code source: https://github.com/vercel/next.js/blob/canary/examples/middleware/middleware.ts
import { NextRequest, NextResponse } from 'next/server'
export function middleware(request: NextRequest) {
if (request.nextUrl.pathname === '/about') {
return NextResponse.redirect(new URL('/redirected', request.url))
}
if (request.nextUrl.pathname === '/another') {
return NextResponse.rewrite(new URL('/rewrite', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/about/:path*', '/another/:path*'],
}
This exmaple is not that scary, but imagine adding more complex logic for few more routes… (ugh)
The solution
Let me introduce to you my latest package called next-easy-middleware.
Installation:
pnpm add next-easy-middleware
npm install next-easy-middleware
yarn add next-easy-middleware
bun add next-easy-middleware
Usage:
import { createMiddleware } from 'next-easy-middlewares';
import { type NextRequest, NextResponse } from 'next/server';
import { analyticsMiddleware } from '@shared/analytics/middleware';
import { authMiddleware, loginMiddleware } from '@/app/(auth)/_middleware';
import { docsMiddleware } from '@/app/(docs)/_middleware';
import { blogMiddleware, blogViewsMiddleware } from '@/app/(blog)/_middleware';
import { postsMiddleware } from '@/app/(posts)/_middleware';
const middlewares = {
'/login': loginMiddleware,
'/docs/:path*: docsMiddleware,
'/blog/[slug]': blogMiddleware,
'/blog/[slug]/view': blogViewsMiddleware,
'regex:^/posts/\\d+$': postsMiddleware,
};
const globalMiddlewares = {
before: authMiddleware,
after: analyticsMiddleware
}
export const middleware = createMiddleware(middlewares, globalMiddlewares);
export const config = {
matcher: ['/((?!api/|_next/|_static|_vercel|[\\w-]+\\.\\w+).*)'],
};
Feedback
I’m awaiting your feedback about that solution, also feelfree to contribute to that package in below repository.
https://github.com/z4nr34l/next-easy-middlewares
Enjoy!
Top comments (0)