Nextjs version: 14.1.0 (app router)
I have a middleware.ts file that I'm using to validate a jwt on only the /account
route.
I've used the config
variable to define a matcher
and passed in /account
as a property, however, my middleware runs on every route I navigate to instead of only /account
.
Here's my code:
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
export async function middleware(request: NextRequest) {
const jwt = request.cookies.get("jwt")?.value;
if (!jwt) return NextResponse.redirect(new URL("/login", request.url));
const isValid = await validateJwt(jwt);
if (!isValid) return NextResponse.redirect(new URL("/login", request.url));
}
export const config = {
matcher: "/account",
};
I have verified the fact that it's running on every route by using logs and by seeing it hit my auth endpoint (from the validateJwt()
function) on every navigation.
Oddly enough, it works completely fine when I use a path like /api/:path*
, which only runs when I call one of my apis.
Worst comes to worst, I have the middleware run on every route and conditionally check the path before running the code, but it seems like this should be working.
Thank you for the help!!
It's crazy how quickly I figured it out - right after giving up and posting the question on StackOverflow. 🤦
For anybody who's facing the same problem, the issue was with the <Link />
component from next/link
prefetching the /account
route on every route, because a link to /account
lived in my navbar.
To disable prefetching, you add these lines to your matcher:
export const config = {
matcher: [
{
source: "/account",
missing: [
{ type: "header", key: "next-router-prefetch" },
{ type: "header", key: "purpose", value: "prefetch" },
],
},
],
};
Taken straight from the Next.js docs: https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher
Oops. I hope this helps somebody else!