Browser SDK
@loginwith/sdk — tokens and sessions in the browser.
The browser SDK ships as @loginwith/sdk on npm and as a CDN bundle at https://<your-slug>.loginwith.dev/cdn/sdk-latest. It’s the same code either way; the CDN build auto-bootstraps a global lgw pre-configured for your org.
Install
npm install @loginwith/sdk
Or load via CDN:
<script defer async src="https://acme.loginwith.dev/cdn/sdk-latest"></script>
Construct
import { LoginWithClient } from "@loginwith/sdk"
const lgw = new LoginWithClient({
loginUrl: "https://acme.loginwith.page",
apiUrl: "https://acme.loginwith.dev",
clientId: "cli_abc",
})
With the CDN bundle, window.lgw is auto-initialized from your host — skip the constructor.
Methods
| Method | Returns | Notes |
|---|---|---|
login(redirectUrl?) | Promise<void> | Starts the OAuth + PKCE dance. |
handleCallback() | Promise<CallbackResult> | Call on every page load; picks up ?code=... and completes the exchange. |
getToken() | string | null | Current access token (sync — it’s in storage). |
getRefreshToken() | string | null | Refresh token if configured. |
refresh() | Promise<TokenResponse | null> | Exchange the refresh token for a new access token. |
logout() | Promise<void> | Clear local state and redirect to the logout endpoint. |
getMe() | Promise<Me | null> | Fetch the current user from the API. |
isAuthenticated() | boolean | True iff getToken() returns a non-expired token. |
Storage
Tokens live in localStorage by default. For in-memory only:
const lgw = new LoginWithClient({
loginUrl, apiUrl, clientId,
storage: "memory",
})
Cross-subdomain sessions
If your app lives on app.acme.com and your LoginWith dashboard is acme.loginwith.app, the SDK will pick up a token minted on the dashboard via a cross-subdomain cookie. This happens automatically during construction — no extra config.
See PKCE for how the verifier is stored and why.