Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Unable to setcookies in app router in Next.js

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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;

>Solution :

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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading