npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

sveltekit-server-session

v0.1.13

Published

This library provides an easy way to start, serve and modify server sessions.

Downloads

10

Readme

SvelteKit Server Session

This library provides an easy way to start, serve and modify server sessions.

Install with:

npm i -D sveltekit-server-session

Usage

  1. Open your src/app.d.ts file and define your session key under interface Locals.
    // See https://kit.svelte.dev/docs/types#app
       
    import type { Session } from 'sveltekit-server-session';
       
    // for information about these interfaces
    declare global {
      namespace App {
        // interface Error {}
        interface Locals {
          // Add type hints to "locals".
          session: Session;
        }
        // interface PageData {}
        // interface PageState {}
        // interface Platform {}
      }
    }
       
    export {};
    This will give you proper type hints when you access your locals property.
  2. Create a new src/hooks.server.js and start the session in your handle function.
    // src/hooks.server.js
    import { session } from 'sveltekit-server-session';
       
    /**
    * @type {import("@sveltejs/kit").Handle}
    */
    export async function handle({ event, resolve }) {
      // Start the session.
      const [ sessionLocal, error ] = await session.start({
        cookies: event.cookies,
      })
    
      // Check for errors.
      if (error) {
        return new Response(error.message, { status: 500 })
      }
    
      // Save session to `locals`.
      event.locals.session = sessionLocal
    
      // Resolve the sveltekit response.
      const response = await resolve(event)
    
      // Adding required headers to the response.
      for (const [key, value] of sessionLocal.response().headers) {
        response.headers.set(key, value)
      }
    
      return response
    }
    This will make sure every api request has access to the session.
  3. Create an api endpoint that updates the session.
    // src/routes/session/quote/update/+server.js
    export async function PUT({ locals, request }) {
      // Get the session data and response function.
      const { data, response } = locals.session
    
      // Update the "quote".
      data.set('quote', await request.text())
    
      // Respond with the new "quote".
      return response(data.get('quote'))
    }
  4. Retrieve the session and load it into the svelte page.
    // src/routes/+page.server.svelte
    /**
    * @type {import("./$types").PageServerLoad}
    */
    export function load({ locals }) {
      // Get the session data.
      const { data } = locals.session
    
      if (!data.has('quote')) {
        // Set a default "quote".
        data.set('quote', 'initial quote')
      }
    
      return {
        // Load the "quote" into the page.
        quote: data.get('quote'),
      }
    }
  5. Create a svelte page.
    <!-- src/routes/+page.svelte -->
    <script>
      // Load session data.
      /** @type {import('./$types').PageData} */
      export let data
    
      let sending = false
    
      async function set() {
        sending = true
        // Update the session.
        await fetch('/session/quote/update', { method: 'PUT', body: data.quote })
        sending = false
      }
    </script>
    
    <textarea bind:value={data.quote}></textarea>
    <br />
    <button disabled={sending} on:mouseup={set}>
      <span>Save</span>
    </button>

Peek 2024-04-01 03-15

Customization

Every single session related operation like validation, creation, update, deletion and so on, is described by SessionInterface.

You can use session.setOperations() to overwrite these operations by providing your own SessionInterface implementation

session.setOperations({
  async exists(id) {
    return ok(map.has(id))
  },
  async isValid(id) {
    const session = map.get(id)
    if (!session) {
      return ok(false)
    }
    return ok(session.getRemainingSeconds() > 0)
  },
  async has(id) {
    return ok(map.has(id))
  },
  async get(id) {
    return ok(map.get(id))
  },
  async set(id, session) {
    map.set(id, session)
    return ok()
  },
  async delete(id) {
    map.delete(id)
    return ok()
  },
})

This is a simple in memory session implementation, but the sky is the limit, you could even fetch and persist sessions to a remote database.

Don't Preload

SvelteKit comes with preload features baked in, however this feature may cause some inconsistent behavior when dealing with sessions.

Consider the following use case,

  1. Let's say I want to modify my session in some way. 1
  2. Then I want to destroy my session, but the act of destroying it takes a while. 2
  3. In the meantime, by mistake, I hover over some link that preloads the previous page, with the old state. 3
  4. Then the session is finally destroyed, in this order. Well as you can see, when I navigate back to that page, the session state is not updated, because according to SvelteKit it has already preloaded it, and we're good to go. 4

Which is obviously wrong.

To fix this you need to disable preloading.

Navigate to your src/app.html file and disable preloading by settings data-sveltekit-preload-data to false on your body element.

<!DOCTYPE html/>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%sveltekit.assets%/favicon.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    %sveltekit.head%
  </head>
  <body data-sveltekit-preload-data="false"> <!-- Here. -->
    <div>%sveltekit.body%</div>
  </body>
</html>

You could technically disable preloading for specific cases and avoid the issue in that way, but at some point your whole application will be filled with links that point to some page that depends on the server session.
It's just simply not worth the headache.

[!NOTE] Obviously you can still enable preload for resources like assets by manually adding the data-sveltekit-preload-data="hover" attribute to specific elements in your page.

Complete Example

You can find a complete example leveraging the recommended usage here.

[!NOTE] Remember to run your SvelteKit server dev at least once to properly generate your glue types.

[!NOTE] Sessions are only directly available under *.server.js and *.server.ts files.
Sessions are meant to be private data, so they will never be directly available under universal files like +page.js, for example.