useAuth
useAuth() is the primary hook for reading authentication state. It returns
the signed-in flags, the current user and userProfile, the user’s
organizations, and the imperative helpers you need to attach a token to a
backend call or sign the user out. For switching the active org or managing
memberships, use useOrganizations().
This is Torii’s curated public auth surface, deliberately kept to the small, familiar shape auth SDKs expose. The provider’s context carries more fields that the SDK’s own components read internally; those are not part of this hook.
When to use it
Section titled “When to use it”- Gate UI on
isSignedIn(or use<SignedIn>/<SignedOut>). - Read the current
user/userProfilefor display. - Get a bearer token for your own backend calls (
getToken(), async, refreshes near expiry). - Sign the user out, or re-fetch the session after a gate completes.
import { useAuth } from '@torii-js/torii-react';
function Account() { const { isLoaded, isSignedIn, userProfile, getToken, signOut } = useAuth();
if (!isLoaded) return null; if (!isSignedIn) return <a href="/sign-in">Sign in</a>;
async function callApi() { const token = await getToken(); await fetch('/api/me', { headers: { Authorization: `Bearer ${token}` } }); }
return ( <> <span>{userProfile?.name ?? userProfile?.email}</span> <button onClick={callApi}>Load</button> <button onClick={() => signOut()}>Sign out</button> </> );}Returns
Section titled “Returns”useAuth() throws if called outside a <ToriiProvider>.
| Name | Type | Description |
|---|---|---|
isLoaded |
boolean |
true once the initial session probe has settled. Render gates should wait for this before trusting isSignedIn. |
isLoading |
boolean |
true while the initial session probe is in flight. |
isSignedIn |
boolean |
true when the user has an active session with no pending gates. |
user |
User | null |
Identity decoded from the JWT (id, emailVerified), or null when signed out. For full fields use userProfile. |
userProfile |
UserProfileData | null |
Full profile from /me: email, name, locale, etc. null until the boot probe resolves. |
organizations |
ClientOrganizationSummary[] |
Organizations the user belongs to in this environment ({ id, name, role, role_name? }); empty when signed out or with no memberships. Use useOrganizations() to switch the active org or manage members. |
require |
(params: { role } | { permission }) => boolean |
Role/permission authorization check. true when the active-organization session satisfies the check, e.g. require({ role: 'org:administrator' }) or require({ permission: 'org:reports:view' }). false with no active org. System permissions (org:sys_*) aren’t in the token, so check the role instead. Declarative form: <Show when={…}>; full guide: Organizations & roles. |
getToken |
(options?: { template?: string }) => Promise<string | null> |
Async. Returns a usable access token, refreshing first if the current one is missing or within ~30s of expiry. Pass { template } to mint a one-off token from a named JWT template for a third-party service (Hasura, Supabase, …); that token is returned to you, not stored as the session token. Resolves null if the session ended (or the named template doesn’t exist). Prefer this when attaching a bearer token to your own requests. |
getAccessToken |
() => string | null |
Sync. Reads the current access token as-is, with no refresh. Returns null when signed out. Use when you need the token synchronously and can tolerate a near-expiry value. |
sessionExpiresAt |
Date | null |
When the current session expires. null when signed out or not yet known. |
getDevSessionToken |
() => string | null |
Sync. The development session token, or null when there isn’t one. Only sandbox environments have one; always null in production. See the note below. |
signIn |
(tokens: AuthTokens) => void |
Apply tokens from a successful sign-in / sign-up response. Flips session state in-page. |
signOut |
() => Promise<void> |
Revoke the session server-side and clear local tokens. |
refreshSession |
() => Promise<void> |
Re-fetch /me and update userProfile + session gates. Call after any action that may clear a session gate. |
currentLanguage |
string |
The active language code. |
setLanguage |
(code: string) => void |
Switch to a different configured language. |
runtimeIncompatible |
boolean |
true once the server reports this SDK build is too old for an endpoint and the page must reload. Read it to render your own refresh prompt (<ToriiProvider> shows one automatically). |
-
getToken()vsgetAccessToken():getToken()is the one to reach for when calling your backend: it refreshes a near-expiry token before handing it back.getAccessToken()is synchronous and never refreshes. For most authed requests, prefer theuseAuthFetch()hook, which attaches the bearer and retries on401for you. -
getDevSessionToken(): only relevant when you host sign-in on a different origin from your app during local development — for example an app onlocalhost:3000signing in on a page served elsewhere. The session cookie is cross-site there, and browsers that block third-party cookies (Safari and Firefox unconditionally) leave your app signed out after a successful sign-in. To hand the session over, redirect back with the token in the URL fragment alongside the access token, and<ToriiProvider>will pick it up and clear it on load:import { HANDOFF_PARAM, useAuth } from '@torii-js/torii-react';const { getAccessToken, getDevSessionToken, sessionExpiresAt } = useAuth();const accessToken = getAccessToken();const devToken = getDevSessionToken();// No dev token means production (or no session): the cookie already reaches// your app, so leave the URL alone.if (accessToken && devToken) {const params = new URLSearchParams({ [HANDOFF_PARAM.accessToken]: accessToken });if (sessionExpiresAt) {params.set(HANDOFF_PARAM.sessionExpiresAt, sessionExpiresAt.toISOString());}params.set(HANDOFF_PARAM.devSessionToken, devToken);window.location.href = `https://myapp.example.com/#${params}`;}HANDOFF_PARAMholds the fragment parameter names the provider reads. Use it rather than writing the keys out — a mismatch is not a type error, the fragment is simply ignored.Both values are required. Gating on the dev token is what keeps this inert in production — never branch on the environment yourself.
access_tokenmust be present too: a fragment without it is ignored entirely, so the dev token alone would be silently discarded. -
Template tokens:
getToken({ template: 'hasura' })mints a one-off token from a named JWT template for a third-party service. It is returned to you (not stored as the session token); resolvesnullif no such template exists. See JWT templates. -
Sign-out routing: drive post-sign-out navigation off
isSignedInflipping tofalse, orevents.onSessionExpiredon<ToriiProvider>.
TypeScript
Section titled “TypeScript”import type { AuthContextValue, User, UserProfileData, ClientOrganizationSummary, AuthTokens,} from '@torii-js/torii-react';