In my SvelteKit site I do a request to my backend inside of the LayoutServerLoad
function, in +layout.server.ts
. Namely when the site is opened with an ?affiliate_id=bla
query parameter, I want to send this to the backend:
import type { LayoutServerLoad } from "./$types";
import { keyBy } from "$lib/utils";
import { backendUrl } from "$lib/config";
export const trailingSlash = "always";
export const load: LayoutServerLoad = async ({ locals, url, fetch }) => {
const affiliate_id = url.searchParams.get("affiliate_id");
if (affiliate_id) {
const headers = {
"Content-Type": "application/json",
"X-CSRFToken": locals.csrfToken,
};
fetch(`${backendUrl}/shop/basket/`, { method: "POST", credentials: "include", headers, body: JSON.stringify({ affiliate_id }) })
.catch(error => {
console.error("Error storing affiliate_id: ", error);
});
}
return {
// I'm returning a bunch of data here
};
};
The problem is that the backend response contains a set-cookie
header and the cookie is not getting stored in the browser.
When I change my load
function to just return the affiliate_id
:
export const load: LayoutServerLoad = async ({ locals, url }) => {
return {
affiliateId: url.searchParams.get("affiliate_id"),
// and more data
};
};
And then make the request inside of +layout.svelte
, then it all works fine.
<script lang="ts">
import type { PageData } from "./$types";
import { onMount } from "svelte";
export let data: PageData;
const { affiliateId } = data;
onMount(async () => {
if (affiliateId) {
// Do the request here
}
});
</script>
<slot />
Now the cookie from the response is stored in the browser just fine.
Why is the cookie not stored when doing the same request in the load
function?
Requests in a server load function are made by the server not the client’s browser; the client will not receive any cookies by default (though there is some logic that forwards cookies when making the request).
The server load function event object has a cookies
property, which could be used to forward cookies. This may be a bit roundabout since the returned header has to be parsed first (you get an error when trying to set a Set-Cookie
header directly).
3