SvelteKit: redirect() not working on server without disabling ssr
Asked Answered
T

2

10

I am using +layout.server.ts to redirect unauthenticated users from accessing authorized routes with this code:

/* +layout.server.ts */

export const load: PageServerLoad = async () => {
    // ...

    if (!isAuthenticatedUser && isAccessingAuthorizedRoute) {
        throw redirect(300, "/sign-in");
    }
}

But when I tested it by accessing an authorized url (let's say /user/profile), the browser gave me this error:

See the error here

I didn't know what was the problem. After some workarounds and debugging, I found out the error was caused by server-side rendering. Because when I turned off the SSR in +layout.server.ts, redirect worked as expected and browser didn't throw any error. To confirm it, I also tried disabling SSR for a single page and only that page was redirecting rightly.

Why is this happening? I want to use redirect() without disabling SSR.

UPDATE: I also tried redirect() in +page.ts, +page.server.ts and +layout.ts. The same error also happened there when ssr was enabled. I don't think my client-side js code is responsible.

Trejo answered 10/10, 2022 at 16:8 Comment(6)
Something else on your code has the error, the variable tagName is undefined and that is breaking on the client side.Cobnut
I will make a fresh project and try to do the same thing with dummy codeTrejo
@ShrijiKondan I have created a new project. There are 3 svelte pages without any client-side code. I did the same on it with dummy variable and logic. I also tried it in +page.ts, +page.server.ts and +layout.ts. But it doesn't work without disabling SSR. It is bothering me so much.Trejo
I am seeing the same issue. the ssr fix works for me too but heaven knows whyYukyukaghir
Mysteriously (to me at least) throwing a redirect wouldn't work inside the try of a try-catch but it would if I placed it straight after.Atonal
@Atonal well of course, redirects are made by throw redirect(...), which is throwing an error. SvelteKit catches that error and handles the redirect, but if you catch the error in a try/catch block then SvelteKit can't handle it. See the note in the docsFreewheel
T
13

I found the problem. The culprit was the status code I was using for redirecting.

I was providing the wrong status code 300:

// ...

    if (!isAuthenticatedUser && isAccessingAuthorizedRoute) {
        // Wrong!
        throw redirect(300, "/sign-in");
    }

// ...

Providing status code 307 solved the problem:

// From Svelte Documentation

export function load({ locals }) {
  if (!locals.user) {
        // Correct!
        throw redirect(307, '/login');
  }
}

Now it works fine with SSR enabled. There was no explanation why I have to use status code 307 to get it working in the documentation. I hope they will explain it in near future.

Trejo answered 11/10, 2022 at 6:47 Comment(3)
Glad you were able to sort this out. I think it should work with 301 and not 300. I am not sure about this.Cobnut
Yeah, it does work with 301, 308.Trejo
This works on load and actions but I can't seem to get redirects to work on server hooks.Squeeze
A
3

Was facing the same problem and figured out the culprit is not the status code but rather the keyword throw, and it works fine on +page.server.ts.

Didn't work:

redirect(302, '/login')

Does work:

throw redirect(302, '/login')
Arborization answered 2/4, 2023 at 10:45 Comment(1)
With SvelteKit v2, this is now the opposite where redirect() alone works. You do not have to throw it. Source: kit.svelte.dev/docs/migrating-to-sveltekit-2Aplite

© 2022 - 2024 — McMap. All rights reserved.