const {
user,
session,
loggedIn,
ready,
signIn,
signUp,
signOut,
fetchSession,
} = useUserSession()
During server-side rendering (SSR), the module initializes empty session state. When the browser loads the page (hydration), a client plugin fetches the actual session.
user and session are null, ready is falseuser and session contain data, ready is trueUse ready or <BetterAuthState> when you need to wait for hydration. Hydration attaches Vue to the server-rendered HTML and makes it interactive.
Database sessions (default): stored in DB, revocable, visible in admin JWE sessions (database-less): encrypted cookie, no server storage
<script setup lang="ts">
const { user, loggedIn, ready } = useUserSession()
</script>
<template>
<div v-if="!ready">Loading...</div>
<div v-else-if="loggedIn">Welcome, {{ user?.name }}</div>
<div v-else>Please log in</div>
</template>
For pages that need session data during SSR without waiting for hydration:
<script setup lang="ts">
definePageMeta({ auth: 'user' })
const { user, ready, fetchSession } = useUserSession()
if (import.meta.server) {
await fetchSession({ headers: useRequestHeaders(['cookie']) })
}
</script>
<template>
<BetterAuthState>
<template #default>
<p v-if="ready">Welcome {{ user?.name }}</p>
</template>
<template #placeholder>
<p>Loading session...</p>
</template>
</BetterAuthState>
</template>
Without server-side session initialization, the page briefly shows a loading state before hydration completes.
Force refresh the session data:
<script setup lang="ts">
const { fetchSession, ready } = useUserSession()
</script>
<template>
<button :disabled="!ready" @click="fetchSession({ force: true })">
Refresh session
</button>
</template>
Configure session duration in your auth config:
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
export default defineServerAuth({
session: {
cookie: {
maxAge: 60 * 60 * 24 * 7, // 7 days
},
},
})