Hooks
Every hook exported from `@ackplus/nest-auth-react`.
Pick the narrowest hook for the job — components that subscribe to less re-render less.
useNestAuth(): AuthContextValue
The full kitchen sink. Returns state, derived booleans, the AuthClient instance, and every auth action.
Every action is an async wrapper around the underlying client method that updates context state on success/failure. Use it when you need both state and actions in one component.
useUser(): ISessionUserData | null
Just the user.
useSession(): ClientSession | null
The session metadata: id, userId, tenantId, expiresAt, createdAt. Not the user — for that, use useUser().
useAccessToken(): string | null
Reads the current access token. Returns null in cookie mode (the token is HttpOnly and never visible to JS).
Use this for one-off integrations that need the raw token — websockets, third-party SDKs that take a JWT. For your own API calls, the AuthClient already attaches it.
useAuthHeaderFn() / useAuthHeaderFnSync()
Both return a stable function (the reference doesn't change on token refresh, so the consumer does not re-render) that yields the current auth headers. Reach for these instead of useAccessToken() + useEffect when decorating requests in a fetch wrapper or a form submit handler.
useAuthHeaderFnSync() is the synchronous variant — it returns () => Record<string, string> reading from the in-memory token mirror (returns {} if it's empty: no login yet or warm-up pending). Use it where you can't await — e.g. an axios.interceptors.request callback — though client.attachToAxios() is usually cleaner for that. Both accept an optional GetAuthHeadersOptions.
useAuthStatus()
Authentication status with derived booleans:
isLoading is true on first mount until the provider has resolved the user. isUnauthenticated is the negation of isAuthenticated — convenient when you want to render a sign-in CTA.
useHasRole(role, matchAll?): boolean
Returns false for unauthenticated users.
useHasPermission(permission, matchAll?): boolean
Same shape as useHasRole, but checks against permissions instead.
Re-render behavior
Each hook subscribes to its own slice of context. useUser() re-renders when sessionData changes; useHasRole('admin') re-renders when the user's roles change. Components that only need a boolean don't re-render on token refresh.
Async-action hook (low-level)
If you want an action without the full context, you can read the client off the provider once:
You can also reach client from anywhere in the tree — there's no need to keep it as state.
useClientConfig() / useMultiAccountEnabled()
Read the backend's public client config (tenant mode, enabled auth methods, registration/MFA options, and whether multi-account is on) so the UI can adapt without hardcoding it.
Multi-account hooks
For logging into several accounts on one client and switching the active one. These live under an <AccountSwitcherProvider> (separate from AuthProvider).
AccountSnapshot
Each entry in accounts (and activeAccount) is an AccountSnapshot:
| Field | Type | Notes |
|---|---|---|
accountId | string | Stable logical key — userId, or userId:tenantId when tenant-scoped |
userId | string? | |
tenantId | string? | |
email | string? | |
label | string? | Display label (best-effort from name/email, or your override) |
tenantName | string? | App-supplied tenant/property name for the switcher UI |
isActive | boolean | Whether this is the active account |
tenantName is app-supplied — the server session carries no tenant display name. Pass it via addAccount/completeMfa options ({ meta: { tenantName } }) or stamp it later with setAccountMeta. It lets a switcher show "Green Valley" vs "Sunrise" instead of an identical shared-owner email on every row.
Naming accounts — setAccountMeta
AccountMeta is { label?: string; tenantName?: string } — both optional, merged over the existing snapshot.
MFA on add — completeMfa
addAccount throws AccountMfaRequiredError when the login needs a second factor. Catch it, show your OTP UI, then hand the error and the verify DTO to completeMfa:
One-shot:
verify2faconsumes the code. If verification succeeds but the commit step throws, do not callcompleteMfaagain (the code is spent) — recover withmanager.commitAccount(pending.client, meta).
See the Multi-account login & switching recipe for the full walkthrough (header and cookie modes).
Related
- Provider.
- Guards.
- Client utilities — the underlying
hasRole/hasPermissionhelpers.