From 490a371c510451048a05263a04fe76673d7c119e Mon Sep 17 00:00:00 2001 From: "neuralnetwork." Date: Sun, 3 May 2026 00:28:19 +0530 Subject: [PATCH] fix spa useSsrCookies default --- .../content/1.getting-started/1.introduction.md | 4 ++-- .../1.getting-started/2.authentication.md | 7 ++++++- src/module.ts | 8 +++++--- src/utils/resolveUseSsrCookies.ts | 3 +++ test/resolveUseSsrCookies.test.ts | 17 +++++++++++++++++ 5 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 src/utils/resolveUseSsrCookies.ts create mode 100644 test/resolveUseSsrCookies.test.ts diff --git a/docs/content/1.getting-started/1.introduction.md b/docs/content/1.getting-started/1.introduction.md index 8d12332ad..2e08608c3 100644 --- a/docs/content/1.getting-started/1.introduction.md +++ b/docs/content/1.getting-started/1.introduction.md @@ -89,11 +89,11 @@ Supabase 'service role key', has super admin rights and can bypass your Row Leve ### `useSsrCookies` -Default: `true` +Default: `true` when SSR is enabled, `false` when `ssr: false`. Controls whether the module uses cookies to share session info between server and client. You *must* enable this option if you need to access session or user info from the server. It will use the SSR client from the [@supabase/ssr](https://github.com/supabase/ssr) library. -When disabled, the module will use the default Supabase client from the [@supabase/supabase-js](https://github.com/supabase/supabase-js) library which stores session info in local storage. This is useful in certain cases, such as statically generated sites or mobile apps where cookies might not be available. +When disabled, the module will use the default Supabase client from the [@supabase/supabase-js](https://github.com/supabase/supabase-js) library which stores session info in local storage. This is useful in certain cases, such as SPA/CSR-only apps, statically generated sites or mobile apps where cookies might not be available. ::warning When `useSsrCookies` is `true` the following options cannot be customized with `clientOptions`: diff --git a/docs/content/1.getting-started/2.authentication.md b/docs/content/1.getting-started/2.authentication.md index ef105ca3e..4f9099131 100644 --- a/docs/content/1.getting-started/2.authentication.md +++ b/docs/content/1.getting-started/2.authentication.md @@ -13,6 +13,12 @@ All you need to do is to create a `login.vue` and `confirm.vue` page in the `pag For advanced users who want to implement the auth behaviour themselves, you can disable or override the [redirect options](/getting-started/introduction#redirect). :: +## SPA / CSR-only mode + +When your Nuxt app uses `ssr: false`, the module defaults [`useSsrCookies`](/getting-started/introduction#usessrcookies) to `false` so the browser client can restore the session from local storage before auth middleware runs. This keeps authenticated users signed in after a hard refresh in SPA mode. + +If you explicitly enable `useSsrCookies` in an SPA, make sure you handle session hydration yourself before protected-route redirects run. + ## Log-in page - `/login` Each time a user is trying to access a page that needs authentication, he will automatically be redirected to the configured log in page. If you want to allow access to "public" page, you just need to add them in the [exclude](/getting-started/introduction#redirectoptions) redirect option. Alternatively, you can enable the redirect only for certain routes using the [include](/getting-started/introduction#redirectoptions) redirect option. @@ -197,4 +203,3 @@ watch(newPassword, () => { ``` If you want to learn more about it, you can read this [section](https://supabase.com/docs/reference/javascript/auth-resetpasswordforemail). - diff --git a/src/module.ts b/src/module.ts index 3d68b8a84..2586a3e28 100644 --- a/src/module.ts +++ b/src/module.ts @@ -7,6 +7,7 @@ import type { CookieOptions } from 'nuxt/app' import type { SupabaseClientOptions } from '@supabase/supabase-js' import type { NitroConfig, NitroRouteConfig } from 'nitropack' import type { RedirectOptions } from './types' +import { resolveUseSsrCookies } from './utils/resolveUseSsrCookies' export * from './types' @@ -87,7 +88,7 @@ export interface ModuleOptions { * Some `clientOptions` are not configurable when this is enabled. See the docs for more details. * * If false, the server will not be able to access the session. - * @default true + * @default true when ssr is enabled, false when ssr: false * @type boolean */ useSsrCookies?: boolean @@ -153,7 +154,7 @@ export default defineNuxtModule({ }, cookieName: 'sb', cookiePrefix: undefined, - useSsrCookies: true, + useSsrCookies: undefined, cookieOptions: { maxAge: 60 * 60 * 8, sameSite: 'lax', @@ -165,6 +166,7 @@ export default defineNuxtModule({ setup(options, nuxt) { const logger = useLogger('@nuxt/supabase') const { resolve, resolvePath } = createResolver(import.meta.url) + const useSsrCookies = resolveUseSsrCookies(options.useSsrCookies, nuxt.options.ssr) // Public runtimeConfig nuxt.options.runtimeConfig.public.supabase = defu(nuxt.options.runtimeConfig.public.supabase, { @@ -174,7 +176,7 @@ export default defineNuxtModule({ redirectOptions: options.redirectOptions, cookieName: options.cookieName, cookiePrefix: options.cookiePrefix, - useSsrCookies: options.useSsrCookies, + useSsrCookies, cookieOptions: options.cookieOptions, clientOptions: options.clientOptions, }) diff --git a/src/utils/resolveUseSsrCookies.ts b/src/utils/resolveUseSsrCookies.ts new file mode 100644 index 000000000..6e255891d --- /dev/null +++ b/src/utils/resolveUseSsrCookies.ts @@ -0,0 +1,3 @@ +export function resolveUseSsrCookies(useSsrCookies: boolean | undefined, ssr: boolean) { + return useSsrCookies ?? ssr !== false +} diff --git a/test/resolveUseSsrCookies.test.ts b/test/resolveUseSsrCookies.test.ts new file mode 100644 index 000000000..9548bfb49 --- /dev/null +++ b/test/resolveUseSsrCookies.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from 'vitest' +import { resolveUseSsrCookies } from '../src/utils/resolveUseSsrCookies' + +describe('resolveUseSsrCookies', () => { + it('defaults to true when Nuxt SSR is enabled', () => { + expect(resolveUseSsrCookies(undefined, true)).toBe(true) + }) + + it('defaults to false when Nuxt SSR is disabled', () => { + expect(resolveUseSsrCookies(undefined, false)).toBe(false) + }) + + it('preserves explicit configuration', () => { + expect(resolveUseSsrCookies(true, false)).toBe(true) + expect(resolveUseSsrCookies(false, true)).toBe(false) + }) +})