#cookies in middleware

1 messages · Page 1 of 1 (latest)

mint vectorBOT
#

Hi @dull oak. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

In Next.js, cookies are read from the Cookies header on the request, and set using the Set-Cookie header on the response. For a single given page load, Middleware and Server Components are executed as part of a single request/response cycle. When the browser receives a Set-Cookie header on a response, it can’t then go back in time to put a different Cookie header on the request it already sent. This is why you might not see the cookies set in the previous route immediately in your middleware. The redirect workaround works because it creates a second request, which will carry the updated Cookie header (source (https://github.com/vercel/next.js/issues/49442)).

For cookies set in middleware, you can work around this problem using a mechanism that allows middleware to “override” what Next will tell Server Components about the value of the Cookie header on the request. Overriding the Cookie header will make Server Component functions like cookies() return different values, even for the same request (source (https://github.com/vercel/next.js/issues/49442)).

Here's an example of how you can do this:

import { NextResponse, type NextRequest } from 'next/server';
import { ResponseCookies, RequestCookies } from 'next/dist/server/web/spec-extension/cookies';
#

function applySetCookie(req: NextRequest, res: NextResponse): void {
// parse the outgoing Set-Cookie header
const setCookies = new ResponseCookies(res.headers);
// Build a new Cookie header for the request by adding the setCookies
const newReqHeaders = new Headers(req.headers);
const newReqCookies = new RequestCookies(newReqHeaders);
setCookies.getAll().forEach((cookie) => newReqCookies.set(cookie));
// set “request header overrides” on the outgoing response
NextResponse.next({
request: { headers: newReqHeaders },
}).headers.forEach((value, key) => {
if (
key === 'x-middleware-override-headers' ||
key.startsWith('x-middleware-request-')
) {
res.headers.set(key, value);
}
});
}

This `applySetCookie(req, res)` function can be dropped into your existing middlewares, which will make the `cookies()` function in Server Components reflect the newly-set cookies as expected (**source** (<https://github.com/vercel/next.js/issues/49442>)).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------