Would it be fine to call server actions during server commponent rendering?
I have a server action (marked with "use server"). Would it be fine to call it during server component rendering (e.g. for setting cookies)? Would this work?
"use server";export async function rotateTokenAction() { const store = cookies(); const token = store.get("token"); const newToken = generateNewTokenFromOldToken(token); store.set("token", newToken);}
A server action executed during a server component render does not act as a server action. It will merely act as a simple JavaScript function. In the above example, store.get("token") works normally because you are allowed to read cookies during a server component render, but store.set("token", newToken) will not work because you are not allowed to set cookies during a server component rendering. So, the above example will not work.
A function exported from a "use server" file only acts as a server action1 when it is called from a client interaction (i.e. triggered from the browser). It could be on a button click event, inside useEffect, or inside the action/formAction props.2 A server component render is not run on the browser, explaining why the function is not run as a server action.
As you've seen above, cookies().set() does not work during a server component render. In fact, it's impossible3 to set cookies that way due to streaming. The server cannot update the response status and headers once streaming has started, which prevents you from setting cookies because that would require updating the Set-Cookie header. Since server component rendering is streamed, you cannot set cookies (or set a custom header or set a custom status code) during a server component render.
Middleware runs on the edge runtime, which is a restricted server-side runtime. Not all Node.js APIs are available. So you'll need generateNewTokenFromOldToken to be compatible with the edge runtime.