Reputation: 185
I am learning next.js and the would like to set a cookie as in the code below.
The code returns an error: "Unhandled Runtime Error. Error: Cookies can only be modified in a Server Action or Route Handler."
I thought nextjs components were server components by default. I am using the app router.
I have googled, and have not managed to solve the issue.
Thank you.
import {cookies} from "next/headers";
function doit() {
return new Promise<string>((resolve, reject) =>
{
setTimeout(
()=>
{
resolve("doit");
}, 2000);
});
}
const Home: React.FC = async () => {
let results:string = await doit();
if(results=="doit")
{
cookies().set("done", "true")
}
return (
<div>
<h1>H1 text</h1>
</div>
);
}
export default Home;
Upvotes: 0
Views: 654
Reputation: 565
As far as I am concerned the Next.js has some limitation. You are trying to set a cookie on the client side within a Next.js component. Next.js has certain restrictions on modifying cookies, and they can only be modified in a Server Action or Route Handler. You have to implement the Server Action/Route Handler then make a request to set the cookies.
import { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
// Rest of implementation goes here
let results: string = await doit();
if (results === 'doit') {
res.setHeader('Set-Cookie', 'done=true');
}
res.status(200).json({ message: 'Success' });
}
function doit() {
return new Promise<string>((resolve, reject) => {
setTimeout(() => {
resolve('doit');
}, 2000);
});
}
That would be the api handler for request for Cookies. You can use fetch/axios to fetch the data from the actual Home component which you sent. Make sure of course to place this on the server-side, f.e some server which provides the responses of your requests.
import { useEffect } from 'react';
import axios from 'axios';
const Home: React.FC = () => {
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get('/api/set-cookie');
console.log(response.data);
} catch (error) {
console.error('Error setting cookie:', error);
}
};
fetchData();
}, []);
return (
<div>
<h1>H1 text</h1>
</div>
);
};
export default Home;
Inside the useEffect
you can implement logic for handling the obtained data, remember also that you should replace /api/set-cookies with your actual path.
This article should be helpful: https://maxschmitt.me/posts/next-js-cookies
Upvotes: 1