Skip to content

Auth State

The client tracks three states:

State Meaning
'loading' Checking for existing session (during initialize())
'authenticated' User is signed in
'unauthenticated' No valid session
const unsubscribe = auth.onAuthStateChange((state, user) => {
  console.log('State:', state);  // 'authenticated' | 'unauthenticated' | 'loading'
  console.log('User:', user);    // AuthUser | null
});

// Later, stop listening
unsubscribe();
const unsubscribe = auth.onAuthStateChange((state, user) => {
  console.log('State:', state);  // 'authenticated' | 'unauthenticated' | 'loading'
  console.log('User:', user);    // AuthUser | null
});

// Later, stop listening
unsubscribe();

The callback fires on:

  • initialize() completing
  • signIn() / signUp() succeeding
  • signOut() completing
  • Token refresh failing (session expired)

When the state is 'authenticated', the user object has:

Field Type Description
id string User UUID
email string Email address
name string | undefined Display name
roles string[] Assigned roles
emailVerified boolean Whether email is verified
avatarUrl string | undefined Profile image URL
createdAt string ISO timestamp
auth.onAuthStateChange((state, user) => {
  if (state === 'authenticated') {
    showApp(user);
  } else if (state === 'unauthenticated') {
    showLoginPage();
  } else {
    showSpinner();
  }
});

await auth.initialize();
auth.onAuthStateChange((state, user) => {
  if (state === 'authenticated') {
    showApp(user);
  } else if (state === 'unauthenticated') {
    showLoginPage();
  } else {
    showSpinner();
  }
});

await auth.initialize();

For React, Vue, and Svelte, the framework integrations handle this automatically — see the framework-specific pages.