Using Sapper, how can I redirect to the index page on a 404 error?
Asked Answered
O

2

10

On a 404 error, I don't want to display a 404 page. Instead, I'd like to redirect back to the index page if the user is logged in or to the login page if the user is logged out. I'm already able to route the user to the login in page from the index page if not signed in, so I may just need to redirect to the index page and have it take care of the reroute to the login in page, although that seems inefficient to have to do two reroutes.

I'm able to accomplish it by re-writing the routes/_error.svelte page to this...

<script>
    import { onMount } from 'svelte';
    onMount(() => {window.location.href = '/'});
</script>

But I'm not very confident it's the best way to accomplish what I want to do. It also redirects for all errors, and in a future project, I may want to show certain errors such as 404, but redirect on other errors like 500.

Does anyone have some insight on how this might be better accomplished using Sapper?

Olcott answered 22/10, 2019 at 1:18 Comment(3)
According to the Sapper docs, both the error object and the HTTP status are made available to the _error.svelte template. So you could choose to redirect only if status === 404, for instance, and display various content for other status codes. Reference here: sapper.svelte.dev/docs#Error_pageNeckwear
Do you think the redirect should be handled in the _error.svelte template using the onMount method, or is there a different way for it to be accomplished on the server end?Olcott
The only negative side-effect I see with your solution is that there is an 'intermediate' render before the redirect happens. Ideally, you might want to handle that redirection in server.js, but then you'd have to find a way to differentiate between existing routes (to be passed on to the sapper middleware) and non-existing ones (to be redirected). Or perhaps it is possible to handle errors with an _error.js server route instead of the _error.svelte client route? Haven't tried it, but it might be worth investigating.Neckwear
A
6

You should try goto function.

import { goto } from '@sapper/app';
goto('your/path');

and if you want to do it in the onMount hook, it should be:

<script>
    import { onMount } from 'svelte';
    import { goto } from '@sapper/app';
    onMount(() => goto('your/path'));
</script>

In your very specific case, if you want to do it on an error criteria on the _error.svelte page, you should choose your path depending on error:

<script>
    import { onMount } from 'svelte';
    import { goto } from '@sapper/app';
    onMount(() => goto(
      error.status === 500
        ? 'path1'
        : error.status === 404
        ? 'path2'
        : 'path3'
    ));
</script>

original GitHub issue here

Alexina answered 4/12, 2019 at 2:27 Comment(4)
This certainly works, but still seems less than ideal. Ultimately, it would be nice if Sapper was able to do server side redirects, because this method still requires two redirects to work, one to the _error page, then one to the redirected page. If I have I any HTML on the _error page, that also flashes before doing the redirect. I submitted PR #960 and #962 to the Sapper Github, which would allow server side redirects. Hopefully something like that is implemented.Olcott
Did you try sapper.svelte.dev/docs#Context this.redirect(statusCode, location) inside preload?Khajeh
I did. It doesn't seem to work if I put it in the _error.svelte file.Olcott
I'm also trying to do "if no file or route redirect to home" -- I bought an old domain which google is giving a lot of 404s for when the bots crawl.Protege
E
0

You can also use the HTML meta tag to redirect. Use it on routes/_error.svelte like this:

<svelte:head>
    <meta http-equiv="refresh" content="0; URL=./index" />
</svelte:head>
Estivation answered 26/3, 2021 at 12:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.