SvelteKit (oidc-client-ts)
See the Applications overview for prerequisites, configuration endpoints, and available scopes.
For client-side applications running in the browser, use the authorization code flow with PKCE. These examples do not use a client secret since the code runs in the user’s browser.
PKCE is required for browser-based clients.
oidc-client-tsenables PKCE by default – no additional configuration is needed. Vouch does not issue refresh tokens, so when the token expires your application should redirect the user to sign in again.
oidc-client-ts provides a certified OpenID Connect client for browser-based applications.
Install the library:
npm install oidc-client-ts
Create an auth service in src/lib/auth.js:
import { UserManager, WebStorageStateStore } from "oidc-client-ts";
const userManager = new UserManager({
authority: "https://us.vouch.sh",
client_id: "your-client-id",
redirect_uri: "https://your-app.example.com/callback",
post_logout_redirect_uri: window.location.origin,
scope: "openid email",
response_type: "code",
userStore: new WebStorageStateStore({ store: window.sessionStorage }),
});
export async function getUser() {
return await userManager.getUser();
}
export async function login() {
await userManager.signinRedirect();
}
export async function logout() {
await userManager.removeUser();
window.location.href = "/";
}
export async function handleCallback() {
return await userManager.signinRedirectCallback();
}
Use it in a page component (src/routes/+page.svelte):
<script>
import { onMount } from "svelte";
import { getUser, login, logout } from "$lib/auth";
let user = $state(null);
let loading = $state(true);
onMount(async () => {
user = await getUser();
loading = false;
});
</script>
{#if loading}
<p>Loading...</p>
{:else if user}
<p>Signed in as {user.profile.email}</p>
{#if user.profile.hardware_verified}
<p><strong>Hardware Verified</strong></p>
{/if}
<button onclick={logout}>Sign out</button>
{:else}
<button onclick={login}>Sign in with Vouch</button>
{/if}
Create a callback page (src/routes/callback/+page.svelte):
<script>
import { onMount } from "svelte";
import { goto } from "$app/navigation";
import { handleCallback } from "$lib/auth";
onMount(async () => {
await handleCallback();
goto("/");
});
</script>
<p>Processing login...</p>
Rich Authorization Requests
To request structured permissions beyond scopes, pass authorization_details as an extra parameter in the UserManager configuration:
const userManager = new UserManager({
// ... other config
extraQueryParams: {
authorization_details: JSON.stringify([
{ type: "account_access", actions: ["read", "transfer"] },
]),
},
});
See the Rich Authorization Requests section for the full authorization_details format.