Files
next.js/test/e2e/app-dir/phase-changes/app/cookies/action-to-render/page.tsx
Janka UrygaandGitHub ceebc676a2 prevent cookies from being set in the wrong phase (#71094)
makes the object returned by `cookies() check if the phase we're
currently in allows mutations.

- `(await cookies()).set(...)` will no longer be allowed in a render
that follows an action (previously, this'd work, because
`actionStore.isAction` is still true during the render!)
- `unstable_after(async () => (await cookies()).set(...))` will error
- `const store = await cookies(); unstable_after(() => store.set(...))`
will now also error

this affects a couple places that mutate cookies in a way that we don't
let userspace code do, like draftmode. to support this, i've added
`workUnitStore.userspaceMutableCookies` and made *only that one* check
for invalid accesses. that's the one we return from `cookies()` in a
mutable context. the rest of the codebase can continue using
`workUnitStore.mutableCookies` without worrying about phase checks.
2024-10-11 23:17:30 +02:00

35 lines
916 B
TypeScript

import { cookies } from 'next/headers'
import * as React from 'react'
export const dynamic = 'force-dynamic'
async function action() {
'use server'
// make sure we return an updated version of the page in the response
;(await cookies()).set('pleaseRenderThePage', Date.now() + '')
}
export default async function Page() {
const timestamp = Date.now()
const cookieStore = await cookies()
const canSetCookies = (() => {
try {
cookieStore.set('illegalCookie', 'i-love-side-effects-in-render')
return true
} catch (err) {
// we want assert on the error message, so don't swallow the error
console.error(err)
return false
}
})()
return (
<>
<div id="timestamp">{timestamp}</div>
<div id="canSetCookies">{JSON.stringify(canSetCookies)}</div>
<form action={action}>
<button type="submit">Submit</button>
</form>
</>
)
}