Skip to content

Commit

Permalink
fix(nuxt): prevent duplicate set-cookie headers (nuxt#28211)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe authored Jul 18, 2024
1 parent 064e7b7 commit 58f4f47
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 1 deletion.
10 changes: 10 additions & 0 deletions packages/nuxt/src/app/composables/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ export function useCookie<T = string | null | undefined> (name: string, _opts?:
const nuxtApp = useNuxtApp()
const writeFinalCookieValue = () => {
if (opts.readonly || isEqual(cookie.value, cookies[name])) { return }
nuxtApp._cookies ||= {}
if (name in nuxtApp._cookies) {
// do not append a second `set-cookie` header
if (isEqual(cookie.value, nuxtApp._cookies[name])) { return }
// warn in dev mode
if (import.meta.dev) {
console.warn(`[nuxt] cookie \`${name}\` was previously set to \`${opts.encode(nuxtApp._cookies[name] as any)}\` and is being overridden to \`${opts.encode(cookie.value as any)}\`. This may cause unexpected issues.`)
}
}
nuxtApp._cookies[name] = cookie.value
writeServerCookie(useRequestEvent(nuxtApp)!, name, cookie.value, opts as CookieOptions<any>)
}
const unhook = nuxtApp.hooks.hookOnce('app:rendered', writeFinalCookieValue)
Expand Down
2 changes: 2 additions & 0 deletions packages/nuxt/src/app/nuxt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ interface _NuxtApp {

[key: string]: unknown

/** @internal */
_cookies?: Record<string, unknown>
/** @internal */
_id?: number
/** @internal */
Expand Down
3 changes: 2 additions & 1 deletion test/fixtures/basic/pages/cookies.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ useCookie<string | null>('set-to-null-with-default', { default: () => 'default'
useCookie('browser-accessed-but-not-used')
useCookie('browser-accessed-with-default-value', { default: () => 'default' })
useCookie('browser-set').value = 'set'
// confirm that it only sets one `set-cookie` header
useCookie('browser-set').value = 'set'
useCookie('browser-set-to-null').value = null
useCookie<string | null>('browser-set-to-null-with-default', { default: () => 'default' }).value = null
Expand All @@ -17,7 +19,6 @@ const objectCookieSecond = useCookie('browser-object-default', {
default: () => ({ foo: 'bar' }),
})
function changeCookie () {
console.log(objectCookie.value, objectCookieSecond.value)
if (objectCookie.value!.foo === 'baz') {
objectCookie.value!.foo = 'bar'
} else {
Expand Down

0 comments on commit 58f4f47

Please sign in to comment.