Before you start, make sure you have a Better Auth instance configured. If you haven't done that yet, check out the installation .
We need to mount the handler to SvelteKit server hook.
import { auth } from "$lib/auth" ;
import { svelteKitHandler } from "better-auth/svelte-kit" ;
export async function handle ({ event , resolve }) {
return svelteKitHandler ({ event, resolve, auth });
}
Create a client instance. You can name the file anything you want. Here we are creating client.ts
file inside the lib/
directory.
import { createAuthClient } from "better-auth/svelte" // make sure to import from better-auth/svelte
export const authClient = createAuthClient ({
// you can pass client configuration here
})
Once you have created the client, you can use it to sign up, sign in, and perform other actions.
Some of the actions are reactive. The client use nano-store to store the state and reflect changes when there is a change like a user signing in or out affecting the session state.
< script lang = "ts" >
import { authClient } from "$lib/client" ;
const session = authClient. useSession ();
</ script >
< div >
{# if $session.data}
< div >
< p >
{$session?.data?.user.name}
</ p >
< button
on : click ={ async () => {
await authClient. signOut ();
}}
>
Sign Out
</ button >
</ div >
{: else }
< button
on : click ={ async () => {
await authClient.signIn. social ({
provider: "github" ,
});
}}
>
Continue with github
</ button >
{/ if }
</ div >
import type { LayoutServerLoad } from './$types' ;
import { error, redirect } from '@sveltejs/kit' ;
import { auth } from '$lib/auth' ;
export const load : LayoutServerLoad = async ({ request }) => {
const session = await auth.api. getSession ({
headers: request.headers
});
if ( ! session) {
console. log ( 'Admin : No session' );
throw redirect ( 302 , '/login' );
}
if (session.user.role !== 'admin' ) {
console. log ( 'Admin : Not admin' );
throw error ( 403 , 'Forbidden' );
}
};
We first get the session and set it to event.locals
import type { Handle } from '@sveltejs/kit' ;
import { auth } from '$lib/auth-client' ;
export const handle : Handle = async ({ event , resolve }) => {
// Get the session
const session = await auth.api. getSession ({
headers: event.request.headers
});
// Set session and user to locals
event.locals.session = session?.data?.session;
event.locals.user = session?.data?.user;
const response = await resolve (event);
return response;
};
Then on the +layout.server.ts of the protected routes
import type { LayoutServerLoad } from './$types' ;
import { error, redirect } from '@sveltejs/kit' ;
export const load : LayoutServerLoad = async ({ locals }) => {
const session = locals.session;
const user = locals.user;
if ( ! session) {
console. log ( 'Admin : No session' );
throw redirect ( 302 , '/login' );
}
if (user?.role !== 'admin' ) {
console. log ( 'Admin : Not admin' );
throw error ( 403 , 'Forbidden' );
}
};
if you do this , make sure to also set the types on your app.d.ts
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
interface Locals {
session : Session | undefined ;
user : User | undefined ;
}
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
}
export { };