Nextjs middleware not redirecting server function invocations
Answered
Giant panda posted this in #help-forum
Giant pandaOP
I stumbled this situation in Nextjs App router. I have middleware which inside has following code:
This normally works e.g. when navigating from URL.
Now, when I arrive at the above middleware when a server function is invoked, the redirect does not happen (although it enters inside
Is this normal behavior? What options do I have in such situation?
[This](https://github.com/vercel/next.js/discussions/64993) is related. I think they suggest there to not handle the server functions in middleware, but then question comes, how to know from middleware if this is a server function or not? IMHO server functions don't start with "api" to check that as one user suggested.
EDIT: it seems in above link the suggestion checks header instead of "api" to bypass server functions in middleware. I will verify that solution when I get to PC and close this if that works.
// If user is on protected route and has no session redirect to login page.
if (isProtectedRoute && !session) {
return NextResponse.redirect(new URL("/login", req.nextUrl));
}
This normally works e.g. when navigating from URL.
Now, when I arrive at the above middleware when a server function is invoked, the redirect does not happen (although it enters inside
if
) and also the server function which trigerred this middleware call is not invoked returning undefined
. See below: startTransition(async () => {
// Invoke the server function, this triggers middleware too - and inside middleware redirect is called
// but redirect does not happen and the addMovie never gets called, returns undefined here
const result = await addMovie(data);
// Then due to result being undefined I get error here
setMessage(result.error ? result.error : result.data);
});
Is this normal behavior? What options do I have in such situation?
[This](https://github.com/vercel/next.js/discussions/64993) is related. I think they suggest there to not handle the server functions in middleware, but then question comes, how to know from middleware if this is a server function or not? IMHO server functions don't start with "api" to check that as one user suggested.
EDIT: it seems in above link the suggestion checks header instead of "api" to bypass server functions in middleware. I will verify that solution when I get to PC and close this if that works.
Answered by Giant panda
It seems answer is this (from the gh link I mentioned):
Somehow I thought initially it was using "api" check to exclude server functions from middleware but I was wrong.
export 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)
*/
{
source:
'/((?!api|_next/static|_next/image|media|fonts|favicon.ico|favicon.png).*)',
missing: [
// Exclude Server Actions
{ type: 'header', key: 'next-action' },
],
},
],
};
Somehow I thought initially it was using "api" check to exclude server functions from middleware but I was wrong.
3 Replies
Server actions should have their own auth checks, do not rely on middleware for it.
async function addMovie(){
const session = await getSession();
// handle case where no session or whatever check you need to do
if(!session) redirect(“/…”);
// continue with your logic
}
Giant pandaOP
@LuisLl No that's not the problem, the problem is due to middleware redirect (which also does not seem to work) the server function never gets called.
Giant pandaOP
It seems answer is this (from the gh link I mentioned):
Somehow I thought initially it was using "api" check to exclude server functions from middleware but I was wrong.
export 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)
*/
{
source:
'/((?!api|_next/static|_next/image|media|fonts|favicon.ico|favicon.png).*)',
missing: [
// Exclude Server Actions
{ type: 'header', key: 'next-action' },
],
},
],
};
Somehow I thought initially it was using "api" check to exclude server functions from middleware but I was wrong.
Answer