Skip to content

Example App

The example-web project is a complete, working demonstration of @authrim/web. It is a static HTML site — no build tools, no framework — that showcases all major authentication flows: Passkey, Email Code, Social Login, and SSO.

Source code: github.com/authrim/example-web

This page walks through the example app’s structure, explains how each page works, and shows how to run it yourself.

example-web/
├── config.js # Authrim configuration (issuer, clientId)
├── index.html # Home page (auth status, SSO, logout)
├── login.html # Login page (Passkey, Email Code, Social)
├── callback.html # OAuth/Social callback handler
├── profile.html # User profile display
└── css/
└── style.css # Styling

No package.json — the SDK is loaded from a CDN:

<script src="https://unpkg.com/@authrim/web@latest/dist/authrim-web.umd.global.js"></script>

All settings are in config.js:

window.AUTHRIM_CONFIG = {
issuer: 'https://your-tenant.authrim.com',
clientId: 'your-client-id',
};

Replace these values with your Authrim tenant URL and client ID from the Admin panel.

Register the following in your Authrim client settings:

SettingValue
Allowed Redirect URIshttps://your-app.example.com/callback.html
Allowed Originshttps://your-app.example.com

The home page checks the user’s authentication status and handles SSO:

flowchart TD
    start["Page Load"] --> init["Initialize SDK<br>(enableOAuth: true)"]
    init --> ssoErr{"SSO error<br>in URL?"}
    ssoErr -->|Yes| clean["Clean URL params"] --> showLogin["Show login button"]
    ssoErr -->|No| checkSession["auth.session.get()"]
    checkSession --> hasSession{"Session<br>exists?"}
    hasSession -->|Yes| showUser["Show user info"]
    hasSession -->|No| ssoAttempted{"SSO already<br>attempted?"}
    ssoAttempted -->|No| trySSO["auth.oauth.trySilentLogin()"]
    ssoAttempted -->|Yes| showLogin

Key implementation details:

  1. SSO flow — On first visit, the app tries auth.oauth.trySilentLogin(), which redirects to the IdP with prompt=none. If the IdP has an active session, the user is silently authenticated. If not, the IdP returns login_required and the app shows the login button.

  2. Loop preventionsessionStorage.setItem('sso_attempted', 'true') prevents infinite SSO redirect loops. The flag is cleared on successful login or explicit logout.

  3. Session display — When authenticated, the page shows the user’s name, email, session ID, and expiration time.

The login page offers three authentication methods:

// Sign in (existing user)
const result = await auth.passkey.login();
if (result.error) {
showStatus(result.error.message, 'error');
} else {
onLoginSuccess(); // Redirect to home
}
// Sign up (new user)
const result = await auth.passkey.signUp({ email: userEmail });

The page checks auth.passkey.isSupported() on load and disables Passkey buttons if WebAuthn is not available.

A two-step flow:

// Step 1: Send code
const sendResult = await auth.emailCode.send(email);
// Step 2: Verify code
const verifyResult = await auth.emailCode.verify(email, code);

The UI switches between an email input form and a code input form.

// Popup-based social login
const result = await auth.social.loginWithPopup('google');
if (result.error) {
showStatus(result.error.message, 'error');
} else {
onLoginSuccess();
}

Each provider opens a popup window for authentication. On success, the popup closes, the SDK returns an AuthResponse, and the login page redirects to home.

This page handles OAuth and social login callbacks:

const auth = await AuthrimWeb.createAuthrim({
issuer: window.AUTHRIM_CONFIG.issuer,
clientId: window.AUTHRIM_CONFIG.clientId,
enableOAuth: true,
});
// 1. Check if this is a silent login callback
const silentResult = await auth.oauth.handleSilentCallback();
if (silentResult.status !== 'error' || silentResult.error !== 'not_silent_login') {
return; // Handled (redirect happens internally)
}
// 2. Check if this is a social login callback
if (auth.social.hasCallbackParams()) {
const result = await auth.social.handleCallback();
if (!result.error) {
window.location.href = 'index.html';
}
}

The callback page checks in order:

  1. Silent login callbackhandleSilentCallback() handles SSO results and redirects accordingly
  2. Social login callbackhandleCallback() completes the social login flow

Displays detailed user and session information:

const { data } = await auth.session.get();
if (data) {
// Display user.id, user.email, user.name, user.emailVerified, etc.
// Display session.id, session.expiresAt
}
Terminal window
cd example-web
npx serve .

Open http://localhost:3000 in your browser.

Install the “Live Server” extension in VS Code and open index.html with Live Server.

Terminal window
cd example-web
python3 -m http.server 3000

Since example-web is a static site, deployment is straightforward:

  1. Push the repository to GitHub
  2. Connect to Cloudflare Pages
  3. Set build output directory to / (or .)
  4. No build command needed

Update config.js with your production issuer and client ID before deploying.

flowchart LR
    home["index.html<br>(Home)"]
    login["login.html<br>(Login)"]
    callback["callback.html<br>(Callback)"]
    profile["profile.html<br>(Profile)"]

    home -->|"Not signed in"| login
    login -->|"Passkey / Email Code"| home
    login -->|"Social Login"| callback --> home
    home -->|"View Profile"| profile
    profile -->|"Sign Out"| home