Skip to main content

Svelte client

WIP

Svelte 4+ store. Single readable store, single signIn / signOut helpers.

Setup

src/lib/auth.ts
import { authCreateStore } from '@gentleduck/auth/client/svelte'

export const auth = authCreateStore({
  baseUrl: '/auth',
})

// auth.session - readable Svelte store of the current session state.
// auth.signIn / auth.signOut / auth.beginProvider - methods.

Usage

<script lang="ts">
  import { auth } from '$lib/auth'

  let email = ''
  let password = ''
  let loading = false
  let error: string | null = null

  async function submit() {
    loading = true
    error = null
    try {
      await auth.signIn({
        providerId: 'password',
        input: { email, password },
      })
    } catch (err: any) {
      error = err.code
    } finally {
      loading = false
    }
  }
</script>

{#if $auth.session === undefined}
  <p>Loading...</p>
{:else if $auth.session === null}
  <form on:submit|preventDefault={submit}>
    <input bind:value={email} type="email" required />
    <input bind:value={password} type="password" required />
    <button disabled={loading}>{loading ? 'Signing in...' : 'Sign in'}</button>
    {#if error}<p style="color:red">{error}</p>{/if}
  </form>
{:else}
  <p>Hi, {$auth.session.identity.profile.displayName}</p>
  <button on:click={() => auth.signOut()}>Sign out</button>
{/if}

$auth.session is the reactive accessor - Svelte subscribes automatically when you reference $store in the template.

SvelteKit (SSR)

src/hooks.server.ts
import { auth as authServer } from '$lib/server/auth'

export const handle = async ({ event, resolve }) => {
  const ctx = await authServer.resolveSession(event.request)
  event.locals.session = ctx
  return resolve(event)
}
src/routes/+layout.server.ts
import type { LayoutServerLoad } from './$types'

export const load: LayoutServerLoad = ({ locals }) => {
  return {
    initialAuthState: locals.session
      ? { session: locals.session.session, identity: locals.session.identity }
      : null,
  }
}
src/lib/auth.ts (client)
import { authCreateStore } from '@gentleduck/auth/client/svelte'

export function makeAuth(initialState: any) {
  return authCreateStore({
    baseUrl: '/auth',
    noInitialFetch: true,
    initialState,
  })
}

Pass data.initialAuthState into makeAuth() from your root +layout.svelte.