A simple, password-based session management library for SvelteKit personal projects.
Uses SvelteKit's experimental remote functions for type-safe client-server communication with progressive enhancement.
^2.49.0 (this library is only intended to use with SvelteKit!)^5.46.0npm install sk-sesher
Add the experimental flag to your svelte.config.js:
// svelte.config.js
export default {
kit: {
experimental: {
remoteFunctions: true
}
}
};
Create a .env file with your password:
SESSION_PASSWORD=your-secret-password
Update your src/app.d.ts:
import type { SessionLocals } from 'sk-sesher';
declare global {
namespace App {
interface Locals extends SessionLocals {}
}
}
export {};
Create or update src/hooks.server.ts:
import { handleSession } from 'sk-sesher';
export const handle = handleSession();
Create src/routes/+layout.server.ts:
export const load = ({ locals }) => {
return {
session: locals.session
};
};
lib folderMake sure to export them from any file ending in .remote.ts.
// src/lib/remote/auth.remote.ts
export { signIn, signOut } from 'sk-sesher/auth/remote';
Create src/routes/+layout.svelte:
<script lang="ts">
import { signIn, signOut } from '$lib/remote/auth.remote.js';
import { invalidateAll } from '$app/navigation';
let { data, children } = $props();
async function handleSignOut() {
await signOut();
await invalidateAll();
}
</script>
{#if data.session.isAuthenticated}
<button onclick={handleSignOut}>Sign Out</button>
{@render children()}
{:else}
<form {...signIn}>
<label>
Password
<input {...signIn.fields._password.as('password')} />
</label>
{#each signIn.fields._password.issues() as issue}
<p class="error">{issue.message}</p>
{/each}
<button disabled={!!signIn.pending}>
{signIn.pending ? 'Signing in...' : 'Sign In'}
</button>
</form>
{/if}
That's it! Your app now has password protection.
import { handleSession } from 'sk-sesher';
export const handle = handleSession({
// Environment variable name for the password
envKey: 'MY_SECRET_PASSWORD', // default: 'SESSION_PASSWORD'
// Cookie name for the session
cookieName: 'auth', // default: 'session'
// Session duration in seconds
maxAge: 60 * 60 * 24 // default: 7 days
});
import { handleSession } from 'sk-sesher';
import { sequence } from '@sveltejs/kit/hooks';
export const handle = sequence(
handleSession()
// your other hooks...
);
This library provides two remote functions for authentication. Please keep in mind to re-export these from your own src/lib folder, otherwise they won't work. And turn on the experimental flags.
signIn (form)A remote form that handles password authentication with progressive enhancement.
<script lang="ts">
import { signIn } from '$lib/remote/auth.remote.js';
import { invalidateAll } from '$app/navigation';
</script>
<form {...signIn}>
<label>
Password
<input {...signIn.fields._password.as('password')} />
</label>
{#each signIn.fields._password.issues() as issue}
<p class="error">{issue.message}</p>
{/each}
<button disabled={!!signIn.pending}>
{signIn.pending ? 'Signing in...' : 'Sign In'}
</button>
</form>
Key features:
{...signIn} onto your <form> element for progressive enhancementsignIn.fields._password.as('password') to get the input attributessignIn.fields._password.issues()signIn.result?.error for server-side errors (e.g., wrong password)signIn.pending to show loading stateNote: The password field is named
_password(with underscore) to prevent it from being sent back to the client on validation errors, as per SvelteKit's sensitive data handling.
signOut (command)A remote command that clears the session cookie.
<script lang="ts">
import { signOut } from '$lib/remote/auth.remote.js';
import { invalidateAll } from '$app/navigation';
async function handleSignOut() {
await signOut();
await invalidateAll(); // Refresh page data to reflect logged-out state
}
</script>
<button onclick={handleSignOut}>Sign Out</button>
sk-sesher| Export | Type | Description |
|---|---|---|
handleSession |
(config?) => Handle |
Creates the session management hook |
SessionConfig |
type |
Configuration options type |
Session |
type |
Session state type ({ isAuthenticated: boolean }) |
SessionLocals |
type |
Type to extend App.Locals |
sk-sesher/auth/remote| Export | Type | Description |
|---|---|---|
signIn |
RemoteForm |
Form-based sign in with progressive enhancement |
signOut |
RemoteCommand |
Signs out and clears the session cookie |
handleSession hook runs on every request, reading the session cookie and populating locals.sessionsignIn is a remote form function that validates the password against the environment variable and sets a secure cookiesignOut is a remote command that clears the session cookiehttpOnly, secure, and use sameSite: 'lax'_password) to prevent it from being echoed back on form errorsMIT