Can't set cookies inside a load function

301 views Asked by At

I'm fairly new to Svelte Kit and I am trying to set a cookie in the load function of my +page.server.js.

Here is the code I have tried:

export const load = ({ cookies }) => {

    cookies.set("username", "foo", {
        secure : false,
        maxAge : 60 * 60 * 24 * 7
    })
    
}

How ever the cookie doesn't get set and I verify this by opening the Application panel of the developer console to check if the cookie has been made.

I also don't get any errors for performing this action.

I can however get previously existing cookies inside the load function without any problems, using cookies.get().

2

There are 2 answers

0
hackerman On BEST ANSWER

After a lot of frustration and agony, I have figured out why my cookies wouldn't get set.

I am using pocketbase for authentication and I am handling the authentication in my hooks.server.js in this way:

import PocketBase from 'pocketbase'
import { serializeNonPOJOs } from '$lib/utils'

export const handle = async ({ event, resolve }) => {
    event.locals.pb = new PocketBase('http://localhost:8090')
    event.locals.pb.authStore.loadFromCookie(event.request.headers.get("cookie") || "")

    try {
        if (event.locals.pb.authStore.isValid) {
            await event.locals.pb.collection('users').authRefresh()
            event.locals.user = serializeNonPOJOs(event.locals.pb.authStore.model)
        }
    } catch(_) {
        event.locals.authStore.clear()
        event.locals.user = undefined
    }

    const response = await resolve(event)

    response.headers.set('set-cookie', event.locals.pb.authStore.exportToCookie({
        secure : false
    }))

    return response
}

The handle function runs on every request to the server and you can read more about it in the official documentation of SvelteKit: https://kit.svelte.dev/docs/hooks#server-hooks-handle

Now the issue is in this specific line of code:

response.headers.set('set-cookie', event.locals.pb.authStore.exportToCookie({
        secure : false
    }))

Here I'm using response.headers.set() to set my authentication cookie which is a problem as it wipes out the entire cookie list and only sets the authentication cookie

In reality I should have been doing this:

response.headers.append('set-cookie', event.locals.pb.authStore.exportToCookie({
        secure : false
    }))

This appends the authentication cookie into the cookie list instead of wiping the entire thing

After making the changes, I got the desired result:

Desired outcome

3
Mihai P. On

Hmmm, I couldn't reproduce, because it worked for me. I am using typescript (as should you, tbh) but this code should more or less work:

+page.server.ts

import type { PageServerLoad } from './$types';


export const load: PageServerLoad = ({cookies}) => {

    cookies.set("test", "val")

    return {}
}

I then went into my chrome browser, and sure enough:

cookie, yay!

Maybe try fiddling around with your cookie options.

PS: Maybe it's mad at you because your load function is not returning anything?