Search code examples
sveltesveltekit

Why does my messageStore resets whenever I edit it in SvelteKit


I am having an issue with messageStore which is a simple writable(""). I use it to display any messages in +layout.svelte

<script>
    import '../app.css';
    import NavBar from '../components/NavBar/index.svelte';
    import Footer from '../components/Footer/index.svelte'
    import Message from '../components/Message/index.svelte'
    import { page } from '$app/stores';
    import { messageStore } from '$lib/stores';


</script>

<main class="w-screen h-full flex flex-col bg-white overflow-y">
    <NavBar />
    <Message message={$messageStore} eye="green" eyeBall="blue" />
    <slot />
    <Footer />
</main>

and let's if there is a user that hasn't logged in tries to go to /admin, in there I have an easy check function if the user is logged in or not in /admin/+page.server.ts:

import type { RequestEvent } from "@sveltejs/kit";
import { redirect } from '@sveltejs/kit';
import { messageStore, redirectToStore } from "$lib/stores";

export const load = ({locals, url}) => {
    if(!locals.user){
        redirectToStore.set(url.pathname);
        messageStore.set("error.login.required");
        throw redirect(302, "/login");
    }
};

and whenever it redirects it isn't showing the component in src/component/Message/index.svelte here:

<script>
    import { t } from '$lib/i18n';
    import Eyes from "../Eyes/index.svelte"
    import { messageStore } from '$lib/stores'

    export let eye;
    export let eyeBall;
    export let message;
</script>

{#if message}
    <div class="w-full h-max py-3 bg-red space-x-5 text-white px-6 flex items-center justify-center"> 
        <div class="float-left px-5 py-3">
            <Eyes eye={eye} eyeBall={eyeBall}/>
        </div>
        <h1 class="h-full flex items-center justify-center text-lg"> 
            <h1>{@html $t(message)}</h1>
        </h1>
    </div>
{/if}

I found out if I reload the page fast enough at /login after being redirected automatically from /admin, I can see message for a brief moment.

Does anyone know how to fix this problem with a writable("")?


Solution

  • I think you have two problems.

    Problem 1

    When you redirect using redirect(302, "/login"), then you send back a redirect instruction to the web browser in the HTTP response. This will cause the web browser to fetch the page it is being redirected to, and all client-side state (like stores) is lost when showing the new page. So if you want to keep that client-side info, you have to redirect on the client using goto instead, as suggested by the docs.

    Problem 2

    You use messageStore on the server. That makes little sense, because each time a user comes to your website, they will get a server-side rendered version of the page, and that version will always use the same messageStore. So all users ends up using the same messageStore, which you probably don't want, since stores are supposed to be one per client. So only use stores in client-side code, and never in code that runs on the server.