vercel / next.js

The React Framework
https://nextjs.org
MIT License
127.07k stars 27.01k forks source link

Can't set cookies with "next/headers" using server actions #50009

Closed KolmschateS closed 1 year ago

KolmschateS commented 1 year ago

Verify canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.1.0: Sun Oct  9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103
    Binaries:
      Node: 16.16.0
      npm: 8.16.0
      Yarn: N/A
      pnpm: N/A
    Relevant packages:
      next: 13.4.2
      eslint-config-next: 13.4.2
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.0.4

Which area(s) of Next.js are affected? (leave empty if unsure)

No response

Link to the code that reproduces this issue

https://github.com/KolmschateS/next-set-cookies-reproduction

To Reproduce

create this Vists.tsx, a Component file

enable server actions in next.config.js file to enable server actions with the following code in the nextconfig json

const nextConfig = {
    experimental: {
        serverActions: true,
      },
}

implement it in a page by using importing < Vistis /> and the error should appear when loading the page the components is in.

import { cookies } from 'next/headers';

async function updateCookie()
  {
      "use server"
      // get visits
      const visits = Number(cookies().get('visits')) || 0

      // @ts-expect-error
      cookies().set('visits', visits + 1)

      return Promise.resolve(visits)
  }

export default function Visits()
{
    return (
        <div className='flex flex-col items-center bg-white mt-6 p-6 text-black'>
            <div>
                <h2 className='text-2xl font-bold'>Visits</h2>
            </div>
            {updateCookie()}
        </div>
        )
}

switch between the main branch and 13-4-2-bug branch to see the different between canary(main) and the 13.4.2 version.

Describe the Bug

I am trying to set a get and set a cookie at the same time to monitor the amount of times a user has visited a page, has to be done for a school assignment. It has to be stored in a cookie.

Next.js 13.4.2 gives me an error that I cannot use cookies.set(), which is described as working in the docs:

Error: ReadonlyRequestCookies cannot be modified

Which should be fixed in 13.4.2 according to this issue. But after updating to 13.4.2 I still get the same error.

Updating to canary gives me another error 18-05-2023 12:00 ET:

Error: Cookies can only be modified in a Server Action or Route Handler.

Which is what I'm doing, if I'm correct.

I'm new to Next, does anybody know a fix or what I'm doing wrong?

Expected Behavior

I expect to be able to set the cookie using the server action.

Which browser are you using? (if relevant)

Firefox Developer edition 114.0b5 (64-bit)

How are you deploying your application? (if relevant)

No response

johnson-jesse commented 1 year ago

Have a look at this example repo and see if that helps @KolmschateS .. On second thought, you're trying to use that cookie setting function in the render and the error tells you why. Error: Cookies can only be modified in a Server Action or Route Handler.

KolmschateS commented 1 year ago

@johnson-jesse True, I got it working with a form, but I am not trying to work with a form here. So I'm curious if there is a use case or workaround possible to use cookies outside of a form. Maybe I have to use the useEffect(), I'll have a look when I have time.

johnson-jesse commented 1 year ago

It will still work as a custom invocation server action or as a use server function passed into a component accessed with useEffect

johnson-jesse commented 1 year ago

@KolmschateS I think it's safe to close this issue

KolmschateS commented 1 year ago

using useEffect and useState to fetch the server action worked. Thanks.

soylemezali42 commented 1 year ago

We can't set the maxAge or other headers in server actions. We need to be able to do it according to the document.

Related Document

Screenshot 2023-05-19 at 15 35 22 Screenshot 2023-05-19 at 15 35 34
KolmschateS commented 1 year ago

@soylemezali42 I got my code to work. This is a seperate issue I think, maybe you can open one?

soylemezali42 commented 1 year ago

@KolmschateS . Thank you for notification. I already have opened a new issue.

github-actions[bot] commented 1 year ago

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.