Replies: 16 comments 15 replies
-
I too am interested in this issue, to be able to opt-out of preflight cache on middleware in Nextjs13 |
Beta Was this translation helpful? Give feedback.
-
Someone found a solution to that? Already tried this for all routes but its only called once. export function middleware(request: NextRequest) {
let response = NextResponse.next();
console.log("Set middleware-cache to no cache");
response.headers.set("x-middleware-cache", "no-cache");
return response;
} |
Beta Was this translation helpful? Give feedback.
-
I'm having the same issue. I'm unable to add authentication logic to my |
Beta Was this translation helpful? Give feedback.
-
This issue also breaks localization according to nextjs internationalization docs. For example after changing the locale, clicking a link with absolute path: /profile/xxx will take you to whatever that was cached (disregarding the cookie). |
Beta Was this translation helpful? Give feedback.
-
I solved the issue by bypassing it in the following way Currently my project is checking jwt token in middleware. Added a router.refresh() function call to the redirected page so that middleware could be triggered again |
Beta Was this translation helpful? Give feedback.
-
Found a solution that works fine for me. Just run router.refresh() to clear a Router cache. |
Beta Was this translation helpful? Give feedback.
-
Has anyone found a solution directly in the middleware? This problem seems so important to me |
Beta Was this translation helpful? Give feedback.
-
Is setting 'x-middleware-cache' as 'no-cache' in headers working for anyone? Here is how it is implemented was implemented earlier, const redirectPathname = await shouldRedirect(request);
if (redirectPathname) {
request.nextUrl.pathname = redirectPathname;
return NextResponse.redirect(request.nextUrl);
} with this approach, redirects were getting cache so I had to use router.refresh() to solve it. I also tried implementing it in this way, const redirectPathname = await shouldRedirect(request);
if (redirectPathname) {
request.nextUrl.pathname = redirectPathname;
const response = NextResponse.rewrite(request.nextUrl, {
headers: { "x-middleware-cache": "no-cache" },
});
return response;
} This didn't make any change to the earlier working (without router.refresh()). |
Beta Was this translation helpful? Give feedback.
-
Still no answer at the middleware-level? This is causing chaos for internationalisation. |
Beta Was this translation helpful? Give feedback.
-
This is causing us real issues at applying authorization to our frontend (with next-auth middleware). It's been over a year, please fix this. |
Beta Was this translation helpful? Give feedback.
-
I recently found that in my case, the Redirects with status 308 (Permanent Redirect) get cached while the 307s (Temporary Redirect) do not. Might help someone out in a hurry... |
Beta Was this translation helpful? Give feedback.
-
Hello guys.
And it worked and it fixed the problem with my private pages after authenticating users in sign in form. |
Beta Was this translation helpful? Give feedback.
-
Did anyone get any middleware-level solution for this? Can't we disable this caching? |
Beta Was this translation helpful? Give feedback.
-
I worked very hard to come up with this solution. It's not the smartest, but this is what I got to. "use client";
import { getSession, handleLogout } from "@/_lib/auth";
import useCart from "@/hooks/useCart";
import { useRouter } from "next/navigation";
import React, {
createContext,
useContext,
useEffect,
useLayoutEffect,
useState,
} from "react";
const AuthContext = createContext("AuthContext");
export const AuthProvider = ({ children }) => {
const [session, setSession] = useState(null);
const { connectCart } = useCart();
const [isLoading, setIsLoading] = useState(true);
const [islogingOut, setIsLoggingOut] = useState(false);
const router = useRouter();
const logOut = async ({ newRoute = "/" } = {}) => {
setIsLoggingOut(true);
try {
await handleLogout();
} catch (error) {
} finally {
router.replace(newRoute);
router.refresh();
connectCart([]);
setIsLoggingOut(false);
setSession(null);
}
};
const signIn = async ({ profile, cart = null, next = "/profile" }) => {
if (cart) connectCart(cart?.items);
setSession(profile); // profile data email user name ...
router.replace(next);
router.refresh();
};
useEffect(() => {
const checkSession = async () => {
try {
setIsLoading(true);
const { profile = null, cart = null } = await getSession();
if (cart) connectCart(cart?.items);
setSession(profile);
} catch (error) {
logOut();
} finally {
setIsLoading(false);
}
};
checkSession();
}, []);
return (
<AuthContext.Provider
value={{
session,
isLoading,
islogingOut,
signIn,
logOut,
}}
>
<>{children}</>
</AuthContext.Provider>
);
};
export const useAuth = ({ withRefresh = false } = {}) => {
if (!withRefresh) return useContext(AuthContext);
const { refresh } = useRouter();
useLayoutEffect(() => {
refresh();
}, []);
return useContext(AuthContext);
};
//export const useAuth = () => useContext(AuthContext); and this is my middleware logic import { NextResponse } from "next/server";
import { AuthRoutes, adminRoutes, unAuthRoutes } from "./routes";
import isIncludes from "./utils/isIncludes";
import decodeToken from "./utils/decodeToken";
export async function middleware(request) {
const { pathname, search = "/profile" } = request.nextUrl;
const isAuth = await decodeToken(request.cookies.get("token")?.value);
const isAdmin = isAuth?.role === "admin";
if (isIncludes(pathname, AuthRoutes) && !isAuth) {
return NextResponse.redirect(
new URL(`/sign-up?next=${pathname.toString()}${search}`, request.nextUrl)
);
}
if (isIncludes(pathname, unAuthRoutes) && isAuth && !isAdmin) {
return NextResponse.redirect(new URL("/profile", request.nextUrl));
}
if (isIncludes(pathname, adminRoutes) && !isAdmin) {
return NextResponse.rewrite(new URL(`/not-found`, request.url));
}
if (!isIncludes(pathname, adminRoutes) && isAdmin) {
return NextResponse.redirect(new URL("/dashboard", request.nextUrl));
}
return NextResponse.next();
}
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}; |
Beta Was this translation helpful? Give feedback.
-
Is Next js 15 gonna fix this given its changes to the caching behavior? |
Beta Was this translation helpful? Give feedback.
-
I found a solution. /** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
staleTimes: {
dynamic: 0,
},
},
};
export default nextConfig; I guess router's cache #66039 is breaking change in Next 15, so you don't need to this option when you start with Next 15. |
Beta Was this translation helpful? Give feedback.
-
I am running a middleware auth check to a
/protected
route using Nextjs 13 and the App directory.Currently, when
<Link href="/protected'>Protected</Link>
on a navbar preforms it's prefetch on the root layout render, middleware will not run again. So if the auth session changes, middleware will not detect a change in the session as the prefetch from the<Link>
is cached which is default behavior and one of the benefits of<Link>
.When adding
prefetch={false}
on the<Link href="/protected">
, middleware will detect every session change which is my goal behavior.#32767 Added a feature to opt-out of preflight cache on middleware but I'm unable to reproduce this behavior with Nextjs13 using the following example:
This example will always route to one route repeatedly as the
x-middleware-cache
:no-cache
seems to be ignored. Middleware will only change the route if the root layout is refreshed (manual refresh).Beta Was this translation helpful? Give feedback.
All reactions