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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With