skip to Main Content

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


  1. Chosen as BEST ANSWER

    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...


  2. The issue is you should use NextResponseNextRequest is read only and is the incoming request, Response is what is sent onward.

    So

    import { NextResponse } from "next/server";
    import type { NextRequest } from "next/server";
    
    export function middleware(request: NextRequest) {
      console.log(`running middleware....`, request.method, request.url);
    
      const response = NextResponse.next();
      response.cookies.set("x-middleware-test", "some test value?!");
    
      return response;
    }
    

    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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search