I want to set/update a cookie on the incoming request in the middleware file before the page or layout reads the cookie, but it seems to not be working. Maybe it’s not possible..
I made a demo project you can clone from github:
https://github.com/TJBlackman/nextjs-middleware-set-cookies-test
// middleware.ts
import type { NextRequest } from "next/server";
export async function middleware(request: NextRequest) {
console.log(`running middleware....`, request.method, request.url);
request.cookies.set("x-middleware-test", "some test value?!"); // <- this line should set a cookie that can be read by layout/page??
}
// layout.tsx
import { cookies } from "next/headers";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const cookieStore = cookies();
const testCookie = cookieStore.get("x-middleware-test");
return (
<html lang="en">
<body>
<h1>Layout cookie: {testCookie?.value || "Not Found"}</h1>
{children}
</body>
</html>
);
}
// page.tsx
import { cookies } from "next/headers";
export default function Home() {
const cookieStore = cookies();
const testCookie = cookieStore.get("x-middleware-test");
return (
<main>
<h2>Page cookie: {testCookie?.value || "Not Found"}</h2>
</main>
);
}
2
Answers
This worked for me in NextJS v14.2.4:
I updated the example repo to demonstrate this working. The NextJS docs are kinda obscure imo...
The issue is you should use
NextResponse
–NextRequest
is read only and is the incoming request, Response is what is sent onward.So
Getting rid of async is a good idea unless you need to await something in the middleware.
More reading – https://nextjs.org/docs/app/building-your-application/routing/middleware#using-cookies