ciscoheat / sveltekit-flash-message

Send temporary data after redirect, usually from endpoints. Works with both SSR and client.
https://www.npmjs.com/package/sveltekit-flash-message
MIT License
244 stars 5 forks source link

Could not show flash message when redirecting. #38

Open Sourabhpatel1 opened 3 months ago

Sourabhpatel1 commented 3 months ago

I am checking if a user is logged in and if true then I am redirecting to the home page but the flash messages wont show +page.server.ts

export const load: PageServerLoad = async ({ request, locals, cookies }) => {
    if (locals.user && locals.session) {
        // setFlash({ type: 'success', message: `Welcome ${locals.user.name} !` }, cookies) or
        return redirect(303, "/", { type: 'error', message: 'You are already logged in.' }, cookies)
    }
    const form = await superValidate(request, zod(loginSchema))
    return { form }
}

+layout.svelte

import { getFlash } from 'sveltekit-flash-message';
import { page } from '$app/stores';
import { toast } from 'svelte-sonner';

const flash = getFlash(page);

$: if ($flash)  {
    console.log('We have flash');
    if ($flash.type === 'error') {
        toast.error($flash?.message, {
        action: {
            label: 'X',
            onClick: () => toast.dismiss()
        },
        duration: 3000
    });
}
if ($flash.type === 'success') {
    toast.success($flash.message, {
        action: {
            label: 'X',
            onClick: () => toast.dismiss()
        },
        duration: 3000
    });
    }
}
ciscoheat commented 3 months ago

The tests I've made are working fine for load function redirects. Take a look at this repo and see if you can reproduce the problem: https://www.sveltelab.dev/l185ux6qusai52s

shyakadavis commented 3 months ago

Hi, everyone;

@Sourabhpatel1, are you modifying/setting cookies elsewhere in your project?

Something I did in the past was overriding the flash message cookies (unintentionally) and it frustrated me how much of an oversight it was on my end.

Try sharing a repro, perhaps snippets of your hooks.server.ts. You might be facing a similar issue I had.

Sourabhpatel1 commented 3 months ago

Yes I am using lucia-auth to set session cookies. Also in the dev tools/storage/cookies I can briefly see the flash cookie but the flash message toast does not appear.

Sourabhpatel1 commented 3 months ago

My hooks.server.ts is really simple.

import { lucia } from "$lib/server/auth";
import type { Handle } from "@sveltejs/kit";

export const handle: Handle = async ({ event, resolve }) => {
    const sessionId = event.cookies.get(lucia.sessionCookieName);
    if (!sessionId) {
        event.locals.user = null;
        event.locals.session = null;
        return resolve(event);
    }

    const { session, user } = await lucia.validateSession(sessionId);
    if (session && session.fresh) {
        const sessionCookie = lucia.createSessionCookie(session.id);
        // sveltekit types deviates from the de-facto standard
        // you can use 'as any' too
        event.cookies.set(sessionCookie.name, sessionCookie.value, {
            path: ".",
            ...sessionCookie.attributes
        });
    }
    if (!session) {
        const sessionCookie = lucia.createBlankSessionCookie();
        event.cookies.set(sessionCookie.name, sessionCookie.value, {
            path: ".",
            ...sessionCookie.attributes
        });
    }
    event.locals.user = user;
    event.locals.session = session;
    return resolve(event);
};
ciscoheat commented 3 months ago

Classic, you need cookies.append instead: https://github.com/ciscoheat/sveltekit-flash-message?tab=readme-ov-file#when-setting-cookies-in-a-response

shyakadavis commented 3 months ago

Classic,

We should put this in a hall of fame @ciscoheat 😂

But, yes, @Sourabhpatel1; that was my guess. You are overwriting your cookies on each navigation and clearing your flash messages in the process.

shyakadavis commented 3 months ago

should do the trick. 🙂

Update:

My bad @Sourabhpatel1 🙁

Just had a look and yes, as @ciscoheat mentioned here I was working with the response header itself.

Sorry, event.cookies don't need append, it's only when you deal directly with headers

response.headers.append(
        'set-cookie',
        pb.authStore.exportToCookie({ httpOnly: true, sameSite: 'Lax', secure: dev ? false : true })
    );
Sourabhpatel1 commented 3 months ago

Classic,

We should put this in a hall of fame @ciscoheat 😂

But, yes, @Sourabhpatel1; that was my guess. You are overwriting your cookies on each navigation and clearing your flash messages in the process.

I tried append without any luck. Screenshot_20240310_004755

here is the repo link https://gitlab.com/sveltekit2/tejas-ki-dukaan

I have tested on firefox and chromium.

ciscoheat commented 3 months ago

Sorry, event.cookies don't need append, it's only when you deal directly with headers. Unfortunately I cannot take a look at the repo since it includes too much extra libraries (database, auth, etc), so if you can minimize it to be just a MRE, I'll take a look at it.

Sourabhpatel1 commented 3 months ago

Sorry, event.cookies don't need append, it's only when you deal directly with headers. Unfortunately I cannot take a look at the repo since it includes too much extra libraries (database, auth, etc), so if you can minimize it to be just a MRE, I'll take a look at it.

Will do asap

julien-blanchon commented 2 months ago

I'm also experimenting the same problem

Pascaltib commented 1 month ago

Same here (also using Lucia auth) :(

ciscoheat commented 1 month ago

I need a MRE repo to investigate this further.

Pascaltib commented 1 month ago

@ciscoheat

Maybe my issue was unrelated. I realized that the redirect was not working because the page I was redirecting from was already under the +layout.svelte file with the flash logic. Meaning that when I would redirect to another page (also covered under this layout) it would not run the getFlash(page) code.

I found that moving the flash logic to a different layout.svelte or page.svelte that needs to be reloaded worked for me.

Not sure if I am solving this issue properly but it worked for me!

Thanks for the great library by the way :)

rzzo commented 1 month ago

I am facing what I think is a very similar issue, I have a very similar setup as far as Lucia, Superforms and Shadcn. I have not been able to make any work around work. As far as shrinking this down I think the issues is coming from from one of these other libs?

My issue when I use redirect (either sveltkit or flash redirect) even when the form submit is successful (the form writes to the db) it returns a 500 fail. I can run the same test using just setFlash no redirecting and everything works just fine.