Browser SDK

Sign people in from the browser — a script tag, or npm.

The browser client runs the whole sign-in in the tab: PKCE, the redirect to your login page, the code exchange, token storage and refresh. Two ways to load it, same code underneath.

Script tag

<script defer src="https://acme.loginwith.dev/cdn/sdk-latest"></script>

<button onclick="lgw.signIn()">Sign in</button>

The script arrives configured for your org — its issuer, its login page and its page’s client — and sets window.lgw. Nothing to paste.

lgw is ready once the lgw:ready event fires on window:

<script>
  addEventListener("lgw:ready", async () => {
    if (await lgw.isAuthenticated()) {
      const me = await lgw.User.me()
      document.querySelector("#who").textContent = me.email
    }
  })
</script>

npm

npm add @loginwith/sveltekit

@loginwith/sveltekit/client is the same client with no SvelteKit dependency — usable from any bundler:

import { createLoginWith } from "@loginwith/sveltekit/client"

const LoginWith = createLoginWith({
  api: "https://acme.loginwith.dev",
  issuer: "https://acme.loginwith.dev/",   // trailing slash
  clientId: "cli_…",
  loginPage: "https://acme.loginwith.page/",
})
const lgw = new LoginWith(window)

// on your /lgw/callback route:
if (await lgw.handleCallback()) location.replace(lgw.takeDestination())

Methods

MethodReturnsNotes
signIn(returnTo?)Promise<void>Script tag only. Goes to the login page; comes back to returnTo (default: here).
getLoginUrl(error?)Promise<URL>The login page URL with a fresh PKCE challenge — for building your own link. Pass an error to have the page show it.
handleCallback()Promise<boolean>Redeems the code on /lgw/callback. Automatic with the script tag.
isAuthenticated()Promise<boolean>Whether a usable token is held.
getAccessToken()Promise<string | null>The current token, renewed transparently. Send it as Authorization: Bearer.
User.me()Promise<User>The signed-in user.
signOut()Promise<void>Revokes the session at the issuer, then forgets it here.
rememberDestination(path) / takeDestination()void / stringWhere to go after sign-in, kept in sessionStorage for the length of one sign-in. signIn() does this for you.
profileUrl()Promise<URL>A one-time link to the user’s hosted profile page (password, MFA, linked accounts) on your login page.
organization()Promise<Organization | null>The org this client belongs to.
currentTenantIdstring | nullThe tenant the current token acts in, read from its tnt claim.
switchTenant(tenantId)Promise<boolean>Trades the token for one in another tenant the user belongs to. The old session ends.
Tenant.mine()Promise<Tenant[]>The tenants the user can enter.
Tenant.create(name) / Tenant.update(id, { name?, logo? }) / Tenant.delete(id)Manage tenants, where the user’s role allows it.

Tokens live in localStorage (lgw:access_token, lgw:refresh_token); the PKCE verifier lives in sessionStorage for the length of one sign-in.