API reference
The public surface of
@thunderid/nuxt, as documented in its reference pages.useThunderID()The `useThunderID` composable provides access to the ThunderID authentication context in Nuxt applications. It exposes reactive auth state and SSR-safe methods for signing in, signing out, and signing up. This composable is auto-imported and available in every component, page, and composable without an explicit import.
isSignedInComputedRefWhether the user is currently authenticated
isLoadingComputedRefWhether an auth operation is in progress
isInitializedComputedRefWhether the SDK has finished initializing
userComputedRef<User \The authenticated user object, or `null` if not signed in
organizationComputedRef<Organization \The current organization context, or `null`
signIn(...args) => PromiseInitiate the sign-in flow
signOut() => PromiseSign out the current user
signUp(...args) => PromiseInitiate the sign-up flow
getAccessToken() => PromiseGet a client-safe access token via `/api/auth/token`
<script setup lang="ts">
const { isSignedIn, user, signIn, signOut } = useThunderID()
</script>
<template>
<div>
<p v-if="isSignedIn">Welcome, {{ user?.displayName }}!</p>
<button v-if="isSignedIn" @click="signOut()">Sign Out</button>
<button v-else @click="signIn()">Sign In</button>
</div>
</template>useUser()The `useUser` composable returns the currently authenticated user object as a reactive computed ref. It is auto-imported and available everywhere without an explicit import.
<script setup lang="ts">
const user = useUser()
</script>
<template>
<div v-if="user">
<h1>{{ user.displayName }}</h1>
<p>{{ user.email }}</p>
</div>
<p v-else>Not signed in.</p>
</template><ChangeCredential />The `ChangeCredential` component renders a form that lets a signed-in user set a new value for one of their own credentials. It collects only a new value and its confirmation, checks it against the applicable rules as the user types, and posts the change through the Nuxt server route to ThunderID. It is auto-registered by the Nuxt module. It reads the rules it needs from the user type schema already resolved by `ThunderIDRoot` (`GET /users/me/meta`), so it adds no network request beyond the write itself. Every default label, placeholder, and message is built from the credential attribute's own `displayName` in that schema, so it always matches whatever an admin named it there. By default it manages the `password` credential. To manage a different one, for example a PIN declared on the user type schema, set `attribute`; render the component once per credential to let a user manage more than one. :::note `ChangeCredential` collects only a new value and its confirmation, not the account's existing value. The self-service credential write path does not verify the current value today, so asking for one would only teach the user a false sense of security. Once server-side current-value verification ships, that field returns without a breaking change to this component's public props. :::
attributeoptionalstringThe credential attribute this instance manages, any attribute the user type schema declares `credential: true` for. Defaults to `'password'`.
cardLayoutoptionalbooleanWhether to wrap the form in a bordered card. Defaults to `false`.
classNameoptionalstringAdditional CSS class added to the root element. Defaults to `''`.
policyoptionalPasswordPolicyThe rules the new value must satisfy. Defaults to the applicable rules from the user type schema.
preferencesoptionalPreferencesComponent-level preference overrides, including i18n.
showRequirementsoptionalbooleanWhether to render the live requirement checklist. Defaults to `true`.
titleoptionalstringOverrides the default `"Change {credential}"` heading. Pass an empty string to omit the heading entirely. Defaults to a translated, schema-derived heading.
<template>
<div>
<h2>Security</h2>
<ChangeCredential />
</div>
</template><Loading />The `Loading` component renders its default slot while the authentication state is being resolved. It is useful for showing skeleton screens or spinners during the initial hydration phase.
<template>
<Loading>
<p>Loading...</p>
</Loading>
<SignedIn>
<p>Welcome back!</p>
</SignedIn>
<SignedOut>
<SignInButton />
</SignedOut>
</template><SignInButton />The `SignInButton` component initiates the sign-in flow when clicked. It is auto-registered by the Nuxt module and requires no imports.
preferencesoptionalPreferencesCustomization options for i18n and theming
<template> <SignInButton /> </template>
<SignOutButton />The `SignOutButton` component signs out the current user when clicked. It is auto-registered by the Nuxt module and requires no imports.
preferencesoptionalPreferencesCustomization options for i18n and theming
<template> <SignOutButton /> </template>
<SignUpButton />The `SignUpButton` component initiates the sign-up flow when clicked. It is auto-registered by the Nuxt module and requires no imports.
preferencesoptionalPreferencesCustomization options for i18n and theming
<template> <SignUpButton /> </template>
<SignedIn />The `SignedIn` component renders its default slot only when the user is authenticated. It is the Vue equivalent of the React `` component and is auto-registered by the Nuxt module.
<template>
<SignedIn>
<p>Welcome! You are signed in.</p>
</SignedIn>
</template><SignedOut />The `SignedOut` component renders its default slot only when the user is **not** authenticated. It is auto-registered by the Nuxt module.
<template>
<SignedOut>
<SignInButton />
</SignedOut>
</template><ThunderIDRoot />The `ThunderIDRoot` component is the root provider for the ThunderID Nuxt SDK. It mounts the full provider tree, including i18n, branding, theme, flow, user, and organization, and must wrap all content that uses ThunderID composables or components.
<template>
<ThunderIDRoot>
<NuxtPage />
</ThunderIDRoot>
</template><User />The `User` component provides access to the authenticated user object via a scoped slot. It is auto-registered by the Nuxt module.
<template>
<User>
<template #default="{ user }">
<div v-if="user">
<h1>Welcome, {{ user.displayName }}!</h1>
<p>{{ user.email }}</p>
</div>
</template>
</User>
</template><UserDropdown />The `UserDropdown` component renders a button showing the user's avatar or name. When clicked, it opens a dropdown menu with links to the user profile and a sign-out action. It is auto-registered by the Nuxt module.
appearanceoptionalAppearanceCustomize the component's visual appearance
preferencesoptionalPreferencesCustomization options for i18n and theming
<template>
<nav>
<SignedIn>
<UserDropdown />
</SignedIn>
<SignedOut>
<SignInButton />
</SignedOut>
</nav>
</template><UserProfile />The `UserProfile` component renders a full profile management interface. Users can view and edit their personal information, change their password, and manage linked accounts. It is auto-registered by the Nuxt module.
appearanceoptionalAppearanceCustomize the component's visual appearance
sectionsoptionalstring[]Restrict which profile sections are shown. Defaults to all sections
preferencesoptionalPreferencesCustomization options for i18n and theming
<template> <UserProfile /> </template>
defineThunderIDMiddleware()`defineThunderIDMiddleware` is a factory function that returns a Nuxt route middleware. It handles authentication guards and scope checks, and redirects unauthenticated users. The module also registers a named `'auth'` middleware that you can apply to any page using `definePageMeta`. It uses `defineThunderIDMiddleware` with its default options.
redirectTostringWhere to redirect unauthenticated (or unauthorized) users
requireScopesstring[]One or more OIDC scopes that must be present in the user's session
<script setup lang="ts">
definePageMeta({ middleware: 'auth' })
</script>
<template>
<h1>Dashboard</h1>
</template>createRouteMatcher()`createRouteMatcher` takes an array of route patterns and returns a predicate function. Call the predicate with a path string to check whether it matches any of the patterns. It is primarily used in global middleware to apply auth guards to a set of routes without adding `definePageMeta` to every page.
import { defineThunderIDMiddleware } from '@thunderid/nuxt'
import { createRouteMatcher } from '@thunderid/nuxt/utils'
const isProtected = createRouteMatcher([
'/dashboard',
'/dashboard/**',
'/account/**',
'/settings/**',
])
export default defineNuxtRouteMiddleware((to) => {
if (isProtected(to.path)) {
return defineThunderIDMiddleware()
}
})Module ConfigurationThe `@thunderid/nuxt` module is configured via the `thunderid` key in `nuxt.config.ts`. The configuration covers credentials, redirect URLs, session handling, and UI preferences.
export default defineNuxtConfig({
modules: ['@thunderid/nuxt'],
thunderid: {
clientId: '<your-client-id>',
clientSecret: '<your-client-secret>',
baseUrl: 'https://localhost:8090',
afterSignInUrl: '/dashboard',
afterSignOutUrl: '/',
scopes: ['openid', 'profile', 'internal_login'],
preferences: {
theme: {
inheritFromBranding: true,
mode: 'system',
},
},
},
})ThunderIDError`ThunderIDError` is the structured error class thrown by the ThunderID Nuxt SDK. It extends `Error` and carries a typed `ErrorCode`, an optional HTTP status code, an optional cause, and optional context metadata.
import { ThunderIDError, ErrorCode } from '@thunderid/nuxt/errors'
import { getValidAccessToken } from '@thunderid/nuxt/server'
export default defineEventHandler(async (event) => {
try {
const token = await getValidAccessToken(event)
return await $fetch('/api/resource', {
headers: { Authorization: `Bearer ${token}` },
})
} catch (err) {
if (err instanceof ThunderIDError) {
if (err.code === ErrorCode.SessionExpired) {
throw createError({ statusCode: 401, statusMessage: 'Session expired' })
}
if (err.code === ErrorCode.TokenRefreshFailed) {
throw createError({ statusCode: 401, statusMessage: 'Could not refresh token' })
}
}
throw err
}
})getThunderIDContext()`getThunderIDContext` returns the ThunderID context object that the SDK's server plugin attaches to each H3 event during SSR. This gives synchronous access to the session and pre-fetched SSR data without an additional async call.
import { getThunderIDContext } from '@thunderid/nuxt/server'
export default defineEventHandler((event) => {
const ctx = getThunderIDContext(event)
return {
isSignedIn: ctx?.isSignedIn ?? false,
sub: ctx?.session?.sub ?? null,
}
})getValidAccessToken()`getValidAccessToken` returns a valid access token for the current session. If the stored access token is expired or about to expire, it automatically uses the refresh token to obtain a new one and updates the session cookie.
import { getValidAccessToken } from '@thunderid/nuxt/server'
export default defineEventHandler(async (event) => {
const accessToken = await getValidAccessToken(event)
const result = await $fetch('https://api.example.com/data', {
headers: { Authorization: `Bearer ${accessToken}` },
})
return result
})requireServerSession()`requireServerSession` reads the ThunderID session from the current H3 event and returns the decoded `ThunderIDSessionPayload`. If no valid session exists, it throws an H3 error with status code `401`.
import { requireServerSession } from '@thunderid/nuxt/server'
export default defineEventHandler(async (event) => {
const session = await requireServerSession(event)
// session is guaranteed to be defined here
return { sub: session.sub }
})useServerSession()`useServerSession` reads the ThunderID session from the current H3 event and returns the decoded `ThunderIDSessionPayload`, or `null` if no valid session exists.
import { useServerSession } from '@thunderid/nuxt/server'
export default defineEventHandler(async (event) => {
const session = await useServerSession(event)
if (!session) {
throw createError({ statusCode: 401, statusMessage: 'Unauthorized' })
}
return { sub: session.sub, scopes: session.scopes }
})