Skip to content

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

OptionTypeDefaultDescription
issuerstringrequiredAuthrim server URL
clientIdstringrequiredOAuth client ID
storageStorageOptions{}Client-side storage settings

StorageOptions

OptionTypeDefaultDescription
prefixstring'authrim_'Key prefix for storage entries
storageStorageType'localStorage'Storage backend
StorageTypeBehavior
'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 initialization
setAuthContext(auth);

Reading Context

import { getAuthContext, hasAuthContext } from '@authrim/sveltekit';
// Get auth client (throws if not set)
const auth = getAuthContext();
// Check if context exists
if (hasAuthContext()) {
const auth = getAuthContext();
}
// ✅ Correct — called at component init
const auth = getAuthContext();
onMount(() => {
// ✅ Use auth here
auth.session.get();
});
function handleClick() {
// ✅ Use auth here
auth.passkey.login();
}
// ❌ Wrong — getAuthContext inside onMount
onMount(() => {
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';
ProviderPurpose
BrowserHttpClientHTTP requests to Authrim server
BrowserCryptoProviderPKCE 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 onMount
onMount(async () => {
const { getAuth } = await import('$lib/auth');
auth = await getAuth();
});
// ❌ Wrong — runs on server too
import { getAuth } from '$lib/auth';
const auth = await getAuth(); // Fails on server

Environment Variables

Use PUBLIC_ prefix for client-accessible env vars:

Terminal window
PUBLIC_AUTHRIM_ISSUER=https://auth.example.com
PUBLIC_AUTHRIM_CLIENT_ID=my-app

Access 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:

FeatureSvelte 5 (Recommended)Svelte 4
Propslet { data } = $props()export let data
Statelet count = $state(0)let count = 0
Derivedconst doubled = $derived(count * 2)$: doubled = count * 2
Effects$effect(() => { ... })$: { ... }
Events (listen)onclick={handler}on:click={handler}
Events (dispatch)Callback propscreateEventDispatcher()
Slots (default){@render children()}<slot />
Slots (named){#snippet name()}{/snippet}<div slot="name">
Slot propsSnippet paramslet: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:

  1. You’re using the same AuthrimClient instance (singleton pattern)
  2. AuthProvider is at the root of your component tree
  3. 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

  1. Register your callback URL in the Authrim Admin panel
  2. Ensure callbackPaths includes your callback route in createAuthHandle()
  3. Check that the callback page calls auth.social.handleCallback()

Check your createAuthHandle() options:

  • secure: true requires HTTPS (use false for local development)
  • sameSite: 'strict' blocks cross-origin redirects (use 'lax' for OAuth flows)
  • httpOnly: true prevents JavaScript access (recommended)

Next Steps