DEV Community

Stefan Schuchlenz
Stefan Schuchlenz

Posted on

How the page load function works in Svelte / SvelteKit

When starting off with SveltKit, I realized that somehow getting an url parameter into a page component wasn't super clear.

The example

Let's say you have a component PostList.svelte which holds some posts which you get from an external API and which you want to link to a url structure like mydomain.com/blog/[id] to show the detail of a blogpost.

Getting the id into the link inside the post loop is easy but then what?

First, let's create a Svelte file in /src/routes/blog named [id].svelte.

This tells SvelteKit that we have a template for /blog/some_id to use for our blog post detail.

Inside this Svelte file, we create the following code:

<script context="module">
  export async function load({page}) {
    const id = page.params.id;
    const url = `https://api.somedomain.tld/posts/${id}`;
    const res = await fetch(url);
    const product = await res.json();
    return {props: {post}}
  }
</script>

<script>
  export let post;
</script>

<h1>{post.title}</h1>
Enter fullscreen mode Exit fullscreen mode

What this does

First, we tell Svelte that we need this JS to run first hand when we call the route, therefore the context="module" part.

Then, we create an async function load which gets the page from our requests - this holds the url params which we assign to a constant in the next line and use it to fetch the data from our API.

Once we've awaited the result we need to transform the resulting promise to json with .json() and return it as props for our Svelte component which then shows the post name in its headline.

This is just a quick and very basic example, more info on enriching your page components with load() functionality can be found in the Svelte docs at https://kit.svelte.dev/docs#loading

Top comments (3)

Collapse
 
cristianvogel profile image
Cristian Vogel

Actually, I think there is a bug in your example. This works for me...


<!-- preloader -->

<script context="module">
    export async function load() {
        const url = `https://jsonplaceholder.typicode.com/todos/1`;
        const res = await fetch(url);
        const post = await res.json();
        return {props: {post}}
    }
</script>



<svelte:head>
    <title>About</title>
</svelte:head>

<!-- component -->
<script>
    export let post; 
    console.log( 'Post -> ' + post.title )
</script>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
cristianvogel profile image
Cristian Vogel • Edited

Thanks for sharing.

In my try out of your code here, I found that the

export let post

and subsequent post.title must have that object name of post (unless I am mistaken)... It didn't work otherwise. Is that the case? If so, why?

Collapse
 
yeehawlerz101 profile image
Neil Master

Because of the data returned. The data comes back as an array so:

data[
{"title": "Post Title",
"id": "123"
}
]
So when you need to read from it you tie together the return name being post to the array. So the Keys (being title & id) will correspond to the value pairs in the json.
Aka
post.title = "Post Title"
post.id = "123"
hope this helps :)