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
| Method | Returns | Notes |
|---|---|---|
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 / string | Where 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. |
currentTenantId | string | null | The 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.