Configuration & Advanced
createAuthrim Configuration
import { createAuthrim } from '@authrim/sveltekit';
const auth = await createAuthrim({ issuer: 'https://auth.example.com', clientId: 'my-app', storage: { prefix: 'authrim_', storage: 'localStorage', // 'memory' | 'sessionStorage' | 'localStorage' },});AuthrimConfig
| Option | Type | Default | Description |
|---|---|---|---|
issuer | string | required | Authrim server URL |
clientId | string | required | OAuth client ID |
storage | StorageOptions | {} | Client-side storage settings |
StorageOptions
| Option | Type | Default | Description |
|---|---|---|---|
prefix | string | 'authrim_' | Key prefix for storage entries |
storage | StorageType | 'localStorage' | Storage backend |
| StorageType | Behavior |
|---|---|
'memory' | In-memory only — lost on page refresh |
'sessionStorage' | Per-tab — cleared when tab closes |
'localStorage' | Persistent — shared across tabs |
Context API
The SDK uses Svelte context to share the auth client across components.
Setting Context
AuthProvider calls setAuthContext(auth) internally. For manual setup:
import { setAuthContext } from '@authrim/sveltekit';
// Inside a Svelte component's initializationsetAuthContext(auth);Reading Context
import { getAuthContext, hasAuthContext } from '@authrim/sveltekit';
// Get auth client (throws if not set)const auth = getAuthContext();
// Check if context existsif (hasAuthContext()) { const auth = getAuthContext();}// ✅ Correct — called at component initconst auth = getAuthContext();
onMount(() => { // ✅ Use auth here auth.session.get();});
function handleClick() { // ✅ Use auth here auth.passkey.login();}// ❌ Wrong — getAuthContext inside onMountonMount(() => { const auth = getAuthContext(); // Throws!});Providers (Advanced)
For advanced customization, you can override the HTTP client, crypto provider, and storage:
import { BrowserHttpClient, BrowserCryptoProvider, createBrowserStorage,} from '@authrim/sveltekit';| Provider | Purpose |
|---|---|
BrowserHttpClient | HTTP requests to Authrim server |
BrowserCryptoProvider | PKCE code verifier/challenge generation |
createBrowserStorage() | Client-side storage abstraction |
Cleanup
When the auth client is no longer needed, call destroy() to clean up:
auth.destroy();This removes event listeners and clears timers. AuthProvider calls this automatically on component destroy.
If you’re not using AuthProvider, you must call destroy() manually:
<script lang="ts"> import { onDestroy } from 'svelte'; import { getAuthContext } from '@authrim/sveltekit';
const auth = getAuthContext();
onDestroy(() => { auth.destroy(); });</script>TypeScript Types
All types are exported from @authrim/sveltekit:
import type { // Config AuthrimConfig, StorageOptions, StorageType,
// Client AuthrimClient,
// Response AuthResponse, AuthError, AuthSessionData,
// Namespaces PasskeyNamespace, EmailCodeNamespace, SocialNamespace, SessionNamespace, ConsentNamespace, DeviceFlowNamespace, CIBANamespace, LoginChallengeNamespace,
// Stores AuthStores, AuthLoadingState,
// Events AuthEventName, AuthEventPayloads, AuthEventHandler,
// Core re-exports Session, User, SocialProvider, PasskeyLoginOptions, PasskeySignUpOptions, PasskeyRegisterOptions, PasskeyCredential, EmailCodeSendOptions, EmailCodeSendResult, EmailCodeVerifyOptions, SocialLoginOptions,} from '@authrim/sveltekit';Server types:
import type { ServerAuthContext, ServerSessionManager, ServerSessionManagerOptions, AuthHandleOptions, AuthLoadOptions,} from '@authrim/sveltekit/server';SSR Considerations
Hydration Safety
AuthProvider uses synchronous SSR sync (_syncFromSSR()) to prevent hydration mismatch. The store values are set before the first render, so $isAuthenticated is correct immediately.
Client-Only Code
createAuthrim() uses browser APIs (fetch, crypto, localStorage). Always call it inside onMount or with a dynamic import:
// ✅ Correct — inside onMountonMount(async () => { const { getAuth } = await import('$lib/auth'); auth = await getAuth();});// ❌ Wrong — runs on server tooimport { getAuth } from '$lib/auth';const auth = await getAuth(); // Fails on serverEnvironment Variables
Use PUBLIC_ prefix for client-accessible env vars:
PUBLIC_AUTHRIM_ISSUER=https://auth.example.comPUBLIC_AUTHRIM_CLIENT_ID=my-appAccess via import.meta.env.PUBLIC_AUTHRIM_ISSUER in client code.
Svelte 4 Compatibility
The SDK components use Svelte 4 syntax internally but work in both Svelte 4 and 5 projects. Here’s a syntax mapping for your app code:
| Feature | Svelte 5 (Recommended) | Svelte 4 |
|---|---|---|
| Props | let { data } = $props() | export let data |
| State | let count = $state(0) | let count = 0 |
| Derived | const doubled = $derived(count * 2) | $: doubled = count * 2 |
| Effects | $effect(() => { ... }) | $: { ... } |
| Events (listen) | onclick={handler} | on:click={handler} |
| Events (dispatch) | Callback props | createEventDispatcher() |
| Slots (default) | {@render children()} | <slot /> |
| Slots (named) | {#snippet name()}{/snippet} | <div slot="name"> |
| Slot props | Snippet params | let:propName |
SDK Component Events
SDK components dispatch events using Svelte 4’s createEventDispatcher. In Svelte 5 projects, both syntaxes work:
<!-- Both work in Svelte 5 --><SignInButton on:success={handleSuccess} /><SignInButton onsuccess={handleSuccess} />SDK Component Slots
SDK components use <slot> and <slot name="...">. In Svelte 5 projects, both syntaxes work:
<!-- Svelte 5 snippet syntax --><ProtectedRoute> <p>Protected content</p> {#snippet loading()} <p>Loading...</p> {/snippet}</ProtectedRoute>
<!-- Svelte 4 slot syntax (also works in Svelte 5) --><ProtectedRoute> <p>Protected content</p> <p slot="loading">Loading...</p></ProtectedRoute>Troubleshooting
”getContext must be called during component initialization”
getAuthContext() was called outside component initialization. Move it to the top level of your <script> block.
”Cannot read properties of null (reading ‘passkey’)”
The auth client is not initialized. Ensure AuthProvider wraps your component tree and the client is created before rendering.
Stores show null after login
Events automatically update stores. If stores don’t update, check that:
- You’re using the same
AuthrimClientinstance (singleton pattern) AuthProvideris at the root of your component tree- You haven’t created a second client instance
SSR hydration mismatch
Ensure you pass initialSession and initialUser to AuthProvider:
<AuthProvider {auth} initialSession={data.auth?.session ?? null} initialUser={data.auth?.user ?? null}>Social login callback not working
- Register your callback URL in the Authrim Admin panel
- Ensure
callbackPathsincludes your callback route increateAuthHandle() - Check that the callback page calls
auth.social.handleCallback()
Cookie not set / session lost
Check your createAuthHandle() options:
secure: truerequires HTTPS (usefalsefor local development)sameSite: 'strict'blocks cross-origin redirects (use'lax'for OAuth flows)httpOnly: trueprevents JavaScript access (recommended)
Next Steps
- Overview — Architecture and API summary
- Installation — Quick start guide
- Web SDK Configuration — Storage and client configuration details