diff --git a/README.md b/README.md index 1006f11f..b42ec109 100644 --- a/README.md +++ b/README.md @@ -600,6 +600,18 @@ This is because the user session is stored in a secure cookie and cannot be acce **This means that you should not rely on the user session during prerendering.** +You may also choose to instruct Nuxt AUth Utils to fetch the user session only on the client side, with the `loadStrategy` option in your `nuxt.config.ts`: + +```ts +export default defineNuxtConfig({ + auth: { + loadStrategy: 'client-only' + } +}) +``` + +When using the `client-only` load strategy, the user session can still be manually fetched on the server side by calling `fetch` from the `useUserSession` composable. + ### `` component You can use the `` component to safely display auth-related data in your components without worrying about the rendering mode. @@ -617,7 +629,7 @@ One common use case if the Login button in the header: ``` -If the page is cached or prerendered, nothing will be rendered until the user session is fetched on the client-side. +If the page is cached or prerendered or the load strategy set as `client-only`, nothing will be rendered until the user session is fetched on the client-side. You can use the `placeholder` slot to show a placeholder on server-side and while the user session is being fetched on client-side for the prerendered pages: diff --git a/src/module.ts b/src/module.ts index b215622e..0be5dfcb 100644 --- a/src/module.ts +++ b/src/module.ts @@ -39,6 +39,11 @@ export interface ModuleOptions { */ scrypt?: ScryptConfig } + /** + * Session load strategy + * @default 'server-first' + */ + loadStrategy?: 'server-first' | 'client-only' } declare module 'nuxt/schema' { @@ -51,6 +56,12 @@ declare module 'nuxt/schema' { */ session: SessionConfig } + + interface PublicRuntimeConfig { + auth: { + loadStrategy: 'server-first' | 'client-only' + } + } } export default defineNuxtModule({ @@ -65,6 +76,7 @@ export default defineNuxtModule({ hash: { scrypt: {}, }, + loadStrategy: 'server-first', }, async setup(options, nuxt) { const resolver = createResolver(import.meta.url) @@ -162,6 +174,11 @@ export default defineNuxtModule({ } } + // Load strategy + runtimeConfig.public.auth = defu(runtimeConfig.public.auth, { + loadStrategy: options.loadStrategy ?? 'server-first', + }) + // WebAuthn settings runtimeConfig.webauthn = defu(runtimeConfig.webauthn, { register: {}, diff --git a/src/runtime/app/plugins/session.client.ts b/src/runtime/app/plugins/session.client.ts index f37e5dad..29ef59b8 100644 --- a/src/runtime/app/plugins/session.client.ts +++ b/src/runtime/app/plugins/session.client.ts @@ -6,7 +6,9 @@ export default defineNuxtPlugin(async (nuxtApp) => { if (!nuxtApp.payload.serverRendered) { await useUserSession().fetch() } - else if (Boolean(nuxtApp.payload.prerenderedAt) || Boolean(nuxtApp.payload.isCached)) { + else if (Boolean(nuxtApp.payload.prerenderedAt) || Boolean(nuxtApp.payload.isCached) + || nuxtApp.$config.public.auth.loadStrategy === 'client-only' + ) { // To avoid hydration mismatch nuxtApp.hook('app:mounted', async () => { await useUserSession().fetch() diff --git a/src/runtime/app/plugins/session.server.ts b/src/runtime/app/plugins/session.server.ts index 5d1795c3..6b4d7376 100644 --- a/src/runtime/app/plugins/session.server.ts +++ b/src/runtime/app/plugins/session.server.ts @@ -8,7 +8,9 @@ export default defineNuxtPlugin({ async setup(nuxtApp) { // Flag if request is cached nuxtApp.payload.isCached = Boolean(useRequestEvent()?.context.cache) - if (nuxtApp.payload.serverRendered && !nuxtApp.payload.prerenderedAt && !nuxtApp.payload.isCached) { + if (nuxtApp.payload.serverRendered && !nuxtApp.payload.prerenderedAt && !nuxtApp.payload.isCached + && nuxtApp.$config.public.auth.loadStrategy !== 'client-only' + ) { await useUserSession().fetch() } },