Skip to content

Events

Overview

The SDK emits events when authentication state changes — login, logout, session expiry, token refresh, and errors. You can subscribe to these events to update your UI, log analytics, or trigger side effects.

Subscribing to Events

Use auth.on() to register an event handler:

const unsubscribe = auth.on('auth:login', (payload) => {
console.log('User logged in:', payload.user);
console.log('Method:', payload.method);
});
// Later: unsubscribe
unsubscribe();

auth.on() returns an unsubscribe function. Call it to remove the handler.

Event Reference

auth:login

Emitted after successful authentication (any method):

auth.on('auth:login', (payload) => {
// payload.session: Session
// payload.user: User
// payload.method: 'passkey' | 'emailCode' | 'social'
});

Fires after:

  • auth.passkey.login() or auth.passkey.signUp()
  • auth.emailCode.verify()
  • auth.social.loginWithPopup() or auth.social.handleCallback()

auth:logout

Emitted after sign-out:

auth.on('auth:logout', (payload) => {
// payload.redirectUri?: string (if RP-initiated logout)
});

Fires after auth.signOut().

session:changed

Emitted when the session state changes:

auth.on('session:changed', (payload) => {
// payload.session: Session | null
// payload.user: User | null
if (payload.session) {
updateHeader(payload.user);
} else {
showLoginButton();
}
});

session:expired

Emitted when the session expires or is revoked:

auth.on('session:expired', (payload) => {
// payload.reason: 'timeout' | 'revoked' | 'logout'
switch (payload.reason) {
case 'timeout':
showMessage('Your session has expired. Please sign in again.');
break;
case 'revoked':
showMessage('Your session was ended by an administrator.');
break;
case 'logout':
// Normal logout — already handled by auth:logout
break;
}
});

token:refreshed

Emitted when tokens are refreshed:

auth.on('token:refreshed', (payload) => {
// payload.session: Session (updated session info)
console.log('Token refreshed. New expiry:', payload.session.expiresAt);
});

auth:error

Emitted when an authentication error occurs:

auth.on('auth:error', (payload) => {
// payload.error: AuthError
console.error('Auth error:', payload.error.message);
// Send to error tracking service
trackError({
code: payload.error.code,
message: payload.error.message,
severity: payload.error.severity,
});
});

Event Summary

EventPayloadWhen
auth:login{ session, user, method }After successful login
auth:logout{ redirectUri? }After sign-out
session:changed{ session, user }Session state change
session:expired{ reason }Session expired/revoked
token:refreshed{ session }Token auto-refresh
auth:error{ error }Authentication error

Patterns

UI State Management

// Update navigation header based on auth state
auth.on('auth:login', ({ user }) => {
document.getElementById('user-name').textContent = user.name;
document.getElementById('auth-section').classList.add('authenticated');
});
auth.on('auth:logout', () => {
document.getElementById('auth-section').classList.remove('authenticated');
});
auth.on('session:expired', () => {
showModal('Session Expired', 'Please sign in again.');
});

Analytics

auth.on('auth:login', ({ method, user }) => {
analytics.track('login', {
method,
userId: user.id,
});
});
auth.on('auth:logout', () => {
analytics.track('logout');
});
auth.on('auth:error', ({ error }) => {
analytics.track('auth_error', {
code: error.code,
message: error.message,
});
});

Multiple Handlers

You can register multiple handlers for the same event:

// Handler 1: Update UI
auth.on('auth:login', ({ user }) => {
updateUI(user);
});
// Handler 2: Track analytics
auth.on('auth:login', ({ method }) => {
analytics.track('login', { method });
});
// Both handlers fire on login

Cleanup

Always unsubscribe when the component or page unmounts:

const handlers = [
auth.on('auth:login', handleLogin),
auth.on('auth:logout', handleLogout),
auth.on('session:expired', handleExpired),
];
// Cleanup
function cleanup() {
handlers.forEach(unsubscribe => unsubscribe());
}
// Example: cleanup on page navigation
window.addEventListener('beforeunload', cleanup);

Next Steps