diff --git a/packages/nuxt/src/app/composables/cookie.ts b/packages/nuxt/src/app/composables/cookie.ts index 45fab10d4..b26330b07 100644 --- a/packages/nuxt/src/app/composables/cookie.ts +++ b/packages/nuxt/src/app/composables/cookie.ts @@ -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) diff --git a/packages/nuxt/src/app/nuxt.ts b/packages/nuxt/src/app/nuxt.ts index 867fc0850..3bd828de9 100644 --- a/packages/nuxt/src/app/nuxt.ts +++ b/packages/nuxt/src/app/nuxt.ts @@ -114,6 +114,8 @@ interface _NuxtApp { [key: string]: unknown + /** @internal */ + _cookies?: Record<string, unknown> /** @internal */ _id?: number /** @internal */ diff --git a/test/fixtures/basic/pages/cookies.vue b/test/fixtures/basic/pages/cookies.vue index 742b6824b..b47ba2910 100644 --- a/test/fixtures/basic/pages/cookies.vue +++ b/test/fixtures/basic/pages/cookies.vue @@ -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 @@ -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 {