Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic routes don't refresh when navigation between them [duplicate]

Tags:

sveltekit

Example project: https://github.com/kevinrenskers/slug.

Basically I have a route /[slug], with the following code:

// +page.svelte
<script lang="ts">
  import type { PageData } from "./$types";
  export let data: PageData;
  const { slug } = data;
</script>

{slug}
// +page.ts
import type { PageLoad } from "./$types";

export const load: PageLoad = async ({ params }) => {
  const slug = params.slug;

  return {
    slug,
  };
};

In my +layout.svelte file I have this very simple navigation:

// +layout.svelte
<a href="/a">A</a> <a href="/b">B</a> <a href="/c">C</a>

<div>
  <slot />
</div>

The problem is that when you click between the three pages, that the contents of the page don't change. So if you go from the homepage to A, it'll say A, but if you then click on B or C, it'll still say A. Until you refresh the page.

Edit:
I figured that replacing const { slug } = data with $: slug = data.slug fixes the issue. So I guess the page isn't recreated when you navigate between the same routes? Kind of confusing, a good explanation would be very welcome.

like image 404
Kevin Renskers Avatar asked Oct 11 '25 10:10

Kevin Renskers


1 Answers

This is indeed due to reactivity as you already found out. To understand what happens you have to understand how Svelte works with normal components (where you would see the same issue)

Let's assume this completely useless component:

<script>
  export let name;
  console.log(name);
</script>

When mounting this component it will correctly log the name passed, however when changing the name passed to the component, the code within script does not get executed again (this in contrast to frameworks like React), and the browser will never log anything to the console again.

Here is where Svelte's reactivity comes in. In Svelte you explicitly tell the compiler: 'If x changes do y'. So to run the log again you would do

$: console.log(name);

Considering this if I would have done

export let name
const NAME = name.toUpperCase();

Then that second line will only be executed once at the initial run and always be the very first name in uppercase.

Now it's easy to understand what is happening in SvelteKit as well. In SvelteKit pages are nothing more than (more advanced) components. So if you go from one page to another under the same slug, it is keeping the current component and updating the data property.

This leads to the following:

// New data is provided when navigating
export let data
// This line never executes again just like in a regular component
const { slug } = data;

And that is all there is to it.

like image 54
Stephane Vanraes Avatar answered Oct 14 '25 05:10

Stephane Vanraes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!