`Server Action` function not being recognised.
Answered
du_cki posted this in #help-forum
du_ckiOP
I have a function that just does
But when I call the function from a Server Component it gives me an error;
Fwiw, I have other functions in this file that is also being exported as a server action and they seem to work for the most part. It's just this function that's causing me problems.
import { cookies } from "next/headers";
export async function logoutUser() {
cookies().delete(COOKIE_NAME);
}
and its in a file that has "use server";
on top of the file. But when I call the function from a Server Component it gives me an error;
⨯ Error: Cookies can only be modified in a Server Action or Route Handler. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#cookiessetname-value-options
at logoutUser (./utils/database/auth.ts:68:67)
at Home (./app/page.tsx:23:75)
at stringify (<anonymous>)
Fwiw, I have other functions in this file that is also being exported as a server action and they seem to work for the most part. It's just this function that's causing me problems.
Answered by Pearls
Again, reason being that the useEffect hook can only be executed on the clientside
28 Replies
we'll im not sure if im fully correct but if you are calling a server action from a server component the cookies wont exist, there is a possibility that this causes the error.
maybe make sure that logoutUser is called from the client. this could be done in multiple ways.
NOTE: im not fully sure that this fixes your problem, but its worth a try.
maybe make sure that logoutUser is called from the client. this could be done in multiple ways.
if (typeof window !== "undefined") {
// Code to execute on the client side
}
useEffect(() => {
// Code to execute on the client side
}, []);
NOTE: im not fully sure that this fixes your problem, but its worth a try.
du_ckiOP
Thought I could mutate cookies from server actions cause of this https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#cookies
errr, I'll try to switch it over to a client component then
Erm is there no other way to mutate the cookies inside server actions?
This throws a wrench in my current design
Im really not sure, but ill look into it.
Velvet ant
how do you use the logoutUser function in the Home page ?
du_ckiOP
It's just being used like this inside a server component
export default async function Home() {
const isLoggedOut = verifyJWTCookieAuth();
if (!isLoggedOut) {
await logoutUser();
return <Login />;
}
redirect("/dashboard");
}
Well you can, but the server action has to be executed from the client for it to work (since when the client executes it the clients cookies basicly gets send to the server action as context)
du_ckiOP
But according to a github issue I skimmed through, apparently I can't mutate (
.set()
/.delete()
) but only can .get()
them on server actions which is really a bummer.Velvet ant
server action can only be invoked in a form or event handler and useEffect
that doesnt make sense does it?
if i had a component like it would work? (it would prob create an infinite loop tho):
if i had a component like it would work? (it would prob create an infinite loop tho):
"use client"
export default function TestComponent() {
logoutUser();
return (<></>);
}
Velvet ant
I guess something like this can be done:
I would use it in the
or maybe the actual case can be resolved in the middleware
'use client'
import { logoutUser } from './actions'
import { useEffect } from 'react'
export function Test() {
useEffect(() => {
updateViews();
}, [])
return null;
}
I would use it in the
<Login />
component directlyor maybe the actual case can be resolved in the middleware
Yeah so basicly just this.
du_ckiOP
Oh lol
I see and understand the issue, the function I'm calling is being called as a server component instead of a server action which is causing the problems,
useEffect
does solve this issue.Thanks y'all, I spent an hour on this mess lol.
Actually true, I'm just gonna put this in a middleware and not look back xd
Yes, its because useEffect waits for the client to have loaded javascript, only then it will execute all the code inside the useEffect (so basicly by using useEffect you are making sure that the code inside it will be executed by the client)
Theres a small problem there i think, ofcourse you can try but the middleware is not a part of the client, i think its ran on the server so useEffect will not be available there.
Velvet ant
cookie can be deleted in the middleware
Yes that is true, but @du_cki wants to put the useEffect example inside of the middleware (which is not possible, it will cause an error)
Again, reason being that the useEffect hook can only be executed on the clientside
Answer
du_ckiOP
Yeah makes a whole lot sense now, lol thanks for the help.
All good! Good luck, i hope everything works out.
du_ckiOP
Thank you.