Authentication
convex-svelte integrates with any authentication provider through a small,
reactive API. The setupAuth() / useAuth() primitives below are the low-level
integration point; on top of them, the Auth adapters section
covers higher-level options that wire a specific auth system to Convex for you.
For background on how authentication works in Convex generally — including
hosted providers and the OpenID Connect model — see
Authentication.
setupAuth / useAuth
setupAuth() accepts a reactive getter returning the auth provider's state
and automatically manages client.setAuth() / client.clearAuth(). This
mirrors React's ConvexProviderWithAuth — when the provider state changes
(sign-in, sign-out, token refresh), the auth lifecycle updates automatically.
<script lang="ts">
import { setupConvex, setupAuth } from "convex-svelte";
import { PUBLIC_CONVEX_URL } from "$env/static/public";
setupConvex(PUBLIC_CONVEX_URL);
// The getter is reactive — when its return values change,
// setupAuth automatically toggles setAuth/clearAuth.
setupAuth(() => ({
isLoading: false,
isAuthenticated: !!session,
fetchAccessToken: async ({ forceRefreshToken }) => {
if (!session) return null;
return await getTokenFromYourAuthProvider({ forceRefreshToken });
},
}));
</script>
useAuth() reads the resulting state in any child component:
<script lang="ts">
import { useAuth, useQuery } from "convex-svelte";
import { api } from "../convex/_generated/api.js";
const auth = useAuth();
const user = useQuery(api.users.getActive, () =>
auth.isAuthenticated ? {} : "skip",
);
</script>
{#if auth.isLoading}
Checking authentication...
{:else if !auth.isAuthenticated}
Please sign in.
{:else}
Welcome, {user.data?.name}!
{/if}
When the auth provider's isAuthenticated changes from true to false (user
signs out), the internal $effect re-runs, calls clearAuth() automatically,
and useAuth().isAuthenticated updates to false. No manual cleanup needed.
SSR initial state
Pass initialState to seed the server render before any client-side $effect
runs:
<script lang="ts">
import { setupConvex, setupAuth } from "convex-svelte";
let { data } = $props(); // from +layout.server.ts
setupConvex(PUBLIC_CONVEX_URL);
setupAuth(
() => ({
isLoading: session.isPending,
isAuthenticated: !!session.data,
fetchAccessToken: async ({ forceRefreshToken }) =>
getToken({ forceRefreshToken }),
}),
{ initialState: { isAuthenticated: data.isAuthenticated } },
);
</script>
The server state is trusted until the client-side auth flow settles, then the client takes over. For authenticated server-side data fetching, see Authenticated fetches.
Auth adapters
The primitives above let you wire up any provider by hand. In practice, most
apps reach for a higher-level adapter that connects a specific auth system to
Convex and calls setupAuth() for you, so useAuth() works out of the box.
Convex Auth
Convex Auth is Convex's built-in, officially documented auth library — authentication runs entirely on your own Convex deployment with no third-party service.
- Svelte adapter:
@mmailaender/convex-auth-svelte(community-maintained) — wires Convex Auth tosetupAuth()/useAuth(), with SvelteKit SSR support.
Convex Better Auth
Convex Better Auth integrates the powerful Better Auth library with Convex.
- Svelte adapter:
@mmailaender/convex-better-auth-svelte(community-maintained) — itscreateSvelteAuthClient()callssetupAuth()internally with a reactive session getter, souseAuth()from either package works. SSR-ready. - UI components: Convex Better Auth UI (community-maintained) — production-ready, shadcn-style auth and organization management for SvelteKit (and Next.js), copied into your project. Gets user and organization management running in minutes while keeping full control of the code.
Hosted providers
Convex also works with hosted identity platforms via OpenID Connect JWTs —
Clerk, WorkOS AuthKit, and
Auth0. There are no dedicated convex-svelte wrappers for
these yet, so in a Svelte app you integrate them through the low-level
setupAuth() pattern: return the provider's reactive
auth state (isLoading, isAuthenticated, fetchAccessToken) from the getter.
Low-level: client.setAuth()
You can also use client.setAuth() directly for custom integrations:
<script lang="ts">
import { useConvexClient } from "convex-svelte";
const client = useConvexClient();
client.setAuth(
async () => {
return await getAuthToken();
},
(isAuthenticated) => {
console.log("Auth state changed:", isAuthenticated);
},
);
</script>
API reference
Authentication exports from convex-svelte:
| Export | Kind | Description |
|---|---|---|
setupAuth(provider, options?) | Function | Set up reactive authentication. Manages setAuth/clearAuth automatically. |
useAuth() | Function | Read auth state (isLoading, isAuthenticated) from context. |
ConvexAuthProvider | Type | Auth provider state: isLoading, isAuthenticated, fetchAccessToken. |
SetupAuthOptions | Type | Options for setupAuth: initialState for SSR hydration. |
UseAuthReturn | Type | Return type of useAuth: isLoading, isAuthenticated. |