The Problem:
I’m using Next.js 13 and want to set up multiple middleware functions for my app. I have one middleware for setting the language and another for redirecting a specific page. The issue is, the second middleware is not working as expected. I’ve checked the code, but I can’t find any syntax errors. It simply doesn’t execute, and I’m not receiving any error messages.
The Solutions:
Solution 1: Create a middleware folder and config file
Create a middleware folder in the root directory and add a config.ts file with this code:
import {NextRequest, NextResponse} from "next/server";
import {default as Authentication, matcher as AuthenticationMatcher} from "@/middleware/authentication";
// import {default as Logging, matcher as LoggingMatcher} from "@/middleware/localization";
interface middlewareType {
middleware: (req: NextRequest) => Promise<NextResponse>
matcher?: string | null | undefined
}
export const middleware: middlewareType[] = [
{
middleware: Authentication,
matcher: AuthenticationMatcher
},
// {
// middleware: Logging,
// matcher: AuthenticationMatcher
// },
]
This file defines the middleware functions and their matchers (paths they apply to).
Solution 2: Move middleware logic into a single exported function
In Next.js 13, only one middleware function can be exported. Therefore, you need to combine the logic from both middleware
and middleware2
into a single exported middleware function. Here’s a modified version of your code:
import { NextResponse, NextRequest } from 'next/server';
import acceptLanguage from 'accept-language';
import { fallbackLng, languages } from './app/i18n/settings';
acceptLanguage.languages(languages);
const cookieName = 'i18next';
export function middleware(request: NextRequest) {
// Logic from middleware2
if (request.nextUrl.pathname.startsWith('/about')) {
return NextResponse.redirect(new URL('/home', request.url));
}
// Logic from middleware
let lng;
if (request.cookies.has(cookieName)) {
lng = acceptLanguage.get(request.cookies.get(cookieName).value);
}
// automatic detect language with browser
// if (!lng) lng = acceptLanguage.get(req.headers.get('Accept-Language'));
if (!lng) lng = fallbackLng;
// Redirect if lng in path is not supported
if (
!languages.some((loc) => request.nextUrl.pathname.startsWith(`/${loc}`)) &&
!request.nextUrl.pathname.startsWith('/_next')
) {
return NextResponse.redirect(new URL(`/${lng}${request.nextUrl.pathname}`, request.url));
}
if (request.headers.has('referer')) {
const refererUrl = new URL(request.headers.get('referer'));
const lngInReferer = languages.find((l) => refererUrl.pathname.startsWith(`/${l}`));
const response = NextResponse.next();
if (lngInReferer) response.cookies.set(cookieName, lngInReferer);
return response;
}
return NextResponse.next();
}
Solution 3: Separate Middleware Functions into Different Files
In Next.js, only one exported middleware function per file is supported. To use multiple middleware functions, create separate files for each function. For example, you can have `middleware1.js` and `middleware2.js` files.
middleware1.js:
import { NextResponse, NextRequest } from 'next/server';
import acceptLanguage from 'accept-language';
import { fallbackLng, languages } from './app/i18n/settings';
acceptLanguage.languages(languages);
const cookieName = 'i18next';
export function middleware(req: any) {
let lng;
if (req.cookies.has(cookieName)) lng = acceptLanguage.get(req.cookies.get(cookieName).value);
if (!lng) lng = fallbackLng;
const response = NextResponse.next();
if (lngInReferer) response.cookies.set(cookieName, lngInReferer);
return response;
}
export const config = {
api: {
bodyParser: false,
},
matcher: ['/((?!api|_next/static|_next/image|assets|favicon.ico|sw.js).*)'],
};
middleware2.js:
import { NextResponse, NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
if (request.nextUrl.pathname.startsWith('/about')) {
return NextResponse.redirect(new URL('/home', request.url));
}
}
Remember to import and use these middleware functions in the appropriate places in your application.
Video Explanation:
The following video, titled "Next.js Middleware & Cors | Nextjs 13 tutorial - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.
Web Dev Roadmap for Beginners (Free!): https://bit.ly/DaveGrayWebDevRoadmap Learn how to apply Next.js middleware in Nextjs 13.
The following video, titled "Next.js Middleware & Cors | Nextjs 13 tutorial - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.
Web Dev Roadmap for Beginners (Free!): https://bit.ly/DaveGrayWebDevRoadmap Learn how to apply Next.js middleware in Nextjs 13.