javascriptnext.jsmiddlewarenextjs14

Set Request Cookie in NextJS v14 Middleware


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>
  );
}

Solution

  • This worked for me in NextJS v14.2.4:

    export async function middleware(request: NextRequest) {
      request.cookies.set("x-middleware-test", "some test value?!");
    
      return NextResponse.next({
        request, // <- overwrite the request object!! yay! :D
      });
    }
    

    I updated the example repo to demonstrate this working. The NextJS docs are kinda obscure imo...

    Edit: Just some more info, which is that you have to set request cookies BEFORE you pass the request object to the NextResponse.next() method. As an example, this will NOT work...

    // example of what does NOT work!!
    export async function middleware(request: NextRequest) {
      const response = NextResponse.next({
        request, // set this object as it is NOW, not including future changes
      });
    
      request.cookies.set("x-middleware-test", "some test value?!");
    
      return response; // won't include set-cookie changes :(
    }