Skip to content

Example App

Overview

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.

Project Structure

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>

Configuration

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.

Admin Panel Setup

Register the following in your Authrim client settings:

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

Page-by-Page Walkthrough

index.html — Home Page

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

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

login.html — Login Page

The login page offers three authentication methods:

Passkey

// 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.

Email Code

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.

Social Login

// Popup-based social login
await auth.social.loginWithPopup('google');
await auth.social.loginWithPopup('github');
await auth.social.loginWithPopup('apple');

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

callback.html — Callback Handler

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

profile.html — Profile Page

Displays detailed user and session information:

const { data } = await auth.session.get();
if (data) {
// Display user.id, user.email, user.name, user.email_verified, etc.
// Display session.id, session.expiresAt
}

Running Locally

Option 1: Simple HTTP Server

Terminal window
cd example-web
npx serve .

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

Option 2: VS Code Live Server

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

Option 3: Python

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

Deploying to Cloudflare Pages

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.

User Flow Summary

flowchart LR
    home["index.html
(Home)"] login["login.html
(Login)"] callback["callback.html
(Callback)"] profile["profile.html
(Profile)"] home -->|"Not signed in"| login login -->|"Passkey / Email Code"| home login -->|"Social Login"| callback --> home home -->|"View Profile"| profile profile -->|"Sign Out"| home

Next Steps