Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/content/1.getting-started/1.introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`:
Expand Down
7 changes: 6 additions & 1 deletion docs/content/1.getting-started/2.authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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).

8 changes: 5 additions & 3 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -153,7 +154,7 @@ export default defineNuxtModule<ModuleOptions>({
},
cookieName: 'sb',
cookiePrefix: undefined,
useSsrCookies: true,
useSsrCookies: undefined,
cookieOptions: {
maxAge: 60 * 60 * 8,
sameSite: 'lax',
Expand All @@ -165,6 +166,7 @@ export default defineNuxtModule<ModuleOptions>({
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, {
Expand All @@ -174,7 +176,7 @@ export default defineNuxtModule<ModuleOptions>({
redirectOptions: options.redirectOptions,
cookieName: options.cookieName,
cookiePrefix: options.cookiePrefix,
useSsrCookies: options.useSsrCookies,
useSsrCookies,
cookieOptions: options.cookieOptions,
clientOptions: options.clientOptions,
})
Expand Down
3 changes: 3 additions & 0 deletions src/utils/resolveUseSsrCookies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function resolveUseSsrCookies(useSsrCookies: boolean | undefined, ssr: boolean) {
return useSsrCookies ?? ssr !== false
}
17 changes: 17 additions & 0 deletions test/resolveUseSsrCookies.test.ts
Original file line number Diff line number Diff line change
@@ -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)
})
})
Loading