Skip to content

Events

@authrim/web exposes auth.on() for authentication-related events. Use it to update UI, record analytics, or clean up local state when the SDK emits a login, logout, or token refresh event.

Most Direct Auth and OAuth errors are returned through AuthResponse<T> instead of being emitted as events. Handle those errors at the call site and use events for cross-cutting side effects.

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.

Emitted after a successful Direct Auth login or Smart Handoff save:

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.handoff.verifyAndSave()

Emitted after auth.signOut():

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

signOutApplicationGroup() and signOutAll() delegate to signOut() and also use this logout event path.

Emitted by the OAuth popup flow after a token set is returned:

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

Direct Auth refresh helpers return values directly and should be handled at the call site.

The public event type also includes these names for compatibility and future/internal integrations:

EventPayloadCurrent guidance
session:changed{ session, user }Prefer explicit session checks and Tab Sync broadcasts
session:expired{ reason }Detect with auth.session.validate() or protected API failures
auth:error{ error }Direct Auth and OAuth methods usually return AuthResponse<T> errors
auth.on('auth:login', ({ user }) => {
document.getElementById('user-name')!.textContent =
user.name ?? user.email ?? '';
document.getElementById('auth-section')!.classList.add('authenticated');
});
auth.on('auth:logout', () => {
document.getElementById('auth-section')!.classList.remove('authenticated');
});
auth.on('auth:login', ({ method, user }) => {
analytics.track('login', {
method,
userId: user.id,
});
});
auth.on('auth:logout', () => {
analytics.track('logout');
});
const result = await auth.emailCode.verify(email, code);
if (result.error) {
analytics.track('auth_error', {
code: result.error.code,
message: result.error.message,
});
showError(result.error.message);
return;
}

You can register multiple handlers for the same event:

auth.on('auth:login', ({ user }) => {
updateUI(user);
});
auth.on('auth:login', ({ method }) => {
analytics.track('login', { method });
});

Always unsubscribe when the component or page unmounts:

const handlers = [
auth.on('auth:login', handleLogin),
auth.on('auth:logout', handleLogout),
auth.on('token:refreshed', handleTokenRefresh),
];
function cleanup() {
handlers.forEach((unsubscribe) => unsubscribe());
}
window.addEventListener('beforeunload', cleanup);