How to route programmatically in SvelteKit?
Asked Answered
M

4

58

I want to be able manage history of my SvelteKit app while simultaneously making sure the whole routing system of SvelteKit doesn't get affected in any way.

Something like:

function routeToPage(route: string) {
   router.push(`/${route}`) // equivalent of this function
}
Mnemosyne answered 30/6, 2021 at 2:8 Comment(0)
M
90

Answering my own question thanks to Theo from SvelteKit Discord:

Use $$app-navigation

import { goto } from '$app/navigation';

function routeToPage(route: string, replaceState: boolean) {
   goto(`/${route}`, { replaceState }) 
}

replaceState == true will replace the route instead of adding to the browser history. So, when you click back, you will not go back to the route you came from.

To go back use History API.

import { goto } from '$app/navigation';

function goBack(defaultRoute = '/home') {
  const ref = document.referrer;
  goto(ref.length > 0 ? ref : defaultRoute)
}
Mnemosyne answered 30/6, 2021 at 2:19 Comment(6)
where does reflength variable come from?Clance
And also where/how would you use goBack()?Harris
reflength is missing the dot operator: ref.lengthLuciferase
This doesn't work, not explanatory enoughSternway
this doesn't work on server, i need to check if server mode and just ignore. seems nothing works on ssr really.Atabrine
state can be used to modify the history: goto(`/${route}`, {state: `/${route}`}); If you want to override the current history entry, use replaceState:trueAlberta
D
37

You can programmatically navigate to a route in Svelte-Kit using the goto function. The most simple implementation would be something like this:

<script> 
  import { goto } from '$app/navigation';
  goto("/route")
</script>

But you can use more advanced options with it as well, which would be passed as a second argument with the target route.

Distemper answered 30/6, 2021 at 2:16 Comment(9)
Cannot call goto(...) on the serverLadybug
This doesn't work properly. Problems occur with page refresh: Cannot call goto(...) on the serverSternway
On the server you should redirect in an endpointJustification
@Theoテオ what do you mean that? can you pls share an exampleCarpal
@Carpal An example would be to big for a comment, but here's the documentation for an endpoint kit.svelte.dev/docs#routing-endpointsJustification
Please post example. Also getting server error.Atabrine
Hope it helps :3 github.com/sveltejs/kit/discussions/3245Surfactant
You can do something like this: `import {browser} from "$app/environment"; if (browser) goto("/route"); You do have to import the goto function as wellMemorial
Alternative to browser: onMount(() => { goto('/route'); });Fabyola
W
7
import { goto } from '$app/navigation';

function routeToPage(route: string) {
  goto(route);
}
Wing answered 30/6, 2022 at 23:58 Comment(0)
M
3

It may be not exactly what you're searching for, but I think it worth mentioning that can make use of the beforeNavigate callback provided by $app/navigation.

then, you can save the nav history in a store to use it across your application in order to manage some special cases.

/routes/__layout.svelte

<script>
$: console.log($previousPage, $nextPage);

import { beforeNavigate } from "$app/navigation";
    beforeNavigate(({ from, to }) => {
    $history = [to.pathname, ...$history];
});
</script>

{#if $history}
  <ul>
    {#each $history as url}
      <li>{url}</li>
    {/each}
  </ul>
{/if history}

side note: from& to are URL Objects from the Web API: https://developer.mozilla.org/en-US/docs/Web/API/URL

/routes/stores.svelte

import { writable } from 'svelte/store';

export const history = writable(['/']);

Here's a demo based on the SvelteKit Demo app:

https://stackblitz.com/edit/sveltejs-kit-template-default-wivfds?file=src%2Froutes%2Fstores.js&terminal=dev

Murdocca answered 24/2, 2022 at 14:59 Comment(2)
The demo crashes with error: Error: Failed to load data at Renderer._load (sveltejskittemplatedefaultwivfds-gpaa--3000.local-corp.webconta…) at async Renderer._get_navigation_result (sveltejskittemplatedefaultwivfds-gpaa--3000.local-corp.webconta…)Extractor
It really rough and ready but it's the todos page that is returning an error, not crashing. I've just removed the api part so you can test it out once againMurdocca

© 2022 - 2024 — McMap. All rights reserved.