Skip to main content

Authentication

For AI agents: see llms.txt for the complete documentation index. Markdown versions are available by adding .md to a page URL or requesting Accept: text/markdown.

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.

src/routes/+layout.svelte
<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:

src/routes/+layout.svelte
<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.

Convex Better Auth​

Convex Better Auth integrates the powerful Better Auth library with Convex.

  • Svelte adapter: @mmailaender/convex-better-auth-svelte (community-maintained) — its createSvelteAuthClient() calls setupAuth() internally with a reactive session getter, so useAuth() 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:

ExportKindDescription
setupAuth(provider, options?)FunctionSet up reactive authentication. Manages setAuth/clearAuth automatically.
useAuth()FunctionRead auth state (isLoading, isAuthenticated) from context.
ConvexAuthProviderTypeAuth provider state: isLoading, isAuthenticated, fetchAccessToken.
SetupAuthOptionsTypeOptions for setupAuth: initialState for SSR hydration.
UseAuthReturnTypeReturn type of useAuth: isLoading, isAuthenticated.