Next.js Discord

Discord Forum

Route handler not setting cookies

Unanswered
Yellow Warbler posted this in #help-forum
Open in Discord
Yellow WarblerOP
Here is the route handler response:

return new Response(data, {
    status: 200,
    headers: {
      "Set-Cookie": `at=${data.accessToken}; Path=/; HttpOnly; SameSite=strict, rt=${data.refreshToken}; Path=/; HttpOnly; SameSite=strict`,
    },
  });

(i assure that data is NOT null)

server component:
export default async function Home() {
  const data = await fetch("http://127.0.0.1:3000/api/login", {
    method: "POST",
    credentials: "include",
    mode: "cors",
    cache: "no-store",
  });

while the set-cookie header IS being set, chrome devtools is not showing any cookies and cookies().getAll() prints an empty array aswell

23 Replies

@joulev Dont fetch your own api routes inside server side environments: * https://discord.com/channels/752553802359505017/752647196419031042/1131131403707371562 * <https://nextjs-discord-common-questions.joulev.dev/fetching-own-api-endpoint-in-react-server-components>
Yellow WarblerOP
I think maybe I should have added some additional context:

I am fetching a Next route handler that is fetching my (external) backend api. I know this isn't the best solution, but I could not figure out any other way to set cookies
My original problem was this:
const res = await fetch(
    `${process.env.NEXT_PUBLIC_API_URL_LOCAL}/auth/login`,
    {
      method: "POST",
      credentials: "include",
      mode: "cors",
      headers: {
        "Content-Type": "application/json",
      },
      cache: "no-store",
      body: JSON.stringify({
        email,
        password,
      }),
    }
  );

  if (!res.ok) {
    return NextResponse.json(null);
  }

  return await res.json();

^ This would respond with the correct set-cookie header, but the cookies would never actually set. So my workaround was to

Server component fetches next route handler
Route handler fetches external api
Route handler sets cookies
Route handler returns response
If i'm doing something way wrong then please correct me (i've been trying to fix this all day)
@joulev for the cookie to work, basically the Set-Cookie header must be send to the browser
Yellow WarblerOP
Is it possible to send cookies through the server? This is for SSR reasons
so if you use a different backend and use a route handler to proxy to it, you must retrieve the header in the route handler and attach it to the response too
Yellow WarblerOP
ill look into that real quick
@Yellow Warbler Is it possible to send cookies through the server? This is for SSR reasons
it is disabled for security reasons; it doesn't make sense for a server to have cookies
cookies only apply to browsers
@joulev so if you use a different backend and use a route handler to proxy to it, you must retrieve the header in the route handler and attach it to the response too
Yellow WarblerOP
return new Response(data, {
    status: 200,
    headers: {
      ...res.headers, <-- is this what you mean?
      "set-cookie": `at=${data.accessToken}; Path=/; HttpOnly; SameSite=strict, rt=${data.refreshToken}; Path=/; HttpOnly; SameSite=strict`,
    },
  });
also you need to check whether res.headers is a Header object or just a plain object
it would be easier if the backend sends the token in the form of response body, then the route handler reads the body and set the cookies there
@joulev also you need to check whether `res.headers` is a `Header` object or just a plain object
Yellow WarblerOP
const newHeaders = new Headers(res.headers);

  return new Response(data, {
    status: 200,
    headers: {
      ...newHeaders,
    },
  });
@joulev it would be easier if the backend sends the token in the form of response body, then the route handler reads the body and set the cookies there
Yellow WarblerOP
Oh yeah I tried doing this but cookies().set() would not set anything for some reason
even when I tested just doing this:
export async function POST(request: Request) {
  cookies().set("hi", "bye");

  // return
}


const data = await fetch("http://127.0.0.1:3000/api/login", {
    method: "POST",
    cache: "no-store",
    credentials: "same-origin",
    mode: "cors",
  });
@joulev the `await fetch` is from the browser right
Yellow WarblerOP
Yes
'use client'
in that case try this
const response = new NextResponse(...);
response.cookies.set("hi", "bye")
untested but it does sound like it should work
Northeast Congo Lion
I'm looking at this error on my own system, very similar problem, using fetch api etc. Response.cookies is undefined.