State in URL: the SvelteKit approach

Justin's profile pic

Justin Ahinon

Last updated on

Enter your email to get this article emailed to you

Some context

Last week, while working on a project for the WNBA at my day job, I came across an interesting task. We were building a component that would display some data fetched on the server side. On the frontend, we would have a dropdown that would allow the user to filter the data by a certain property.

The data we were fetching was big enough that we didn’t want to fetch it all at once. Instead, we only fetch on page load a part of it and update the UI every time the user changes the filter.

We were working with Next.js, so I used  getServerSideProps getServerSideProps  to fetch the data and some states to keep track of the current filter. To update the data on filter change, I used Next.js router  to push a new URL with the new filter as a query parameter. This triggered a new server-side render, and the component was updated with the new data.

While working on this component, I wondered how to do the same thing with SvelteKit.

This blog post is a summary of the approach I’d use to build the same component in SvelteKit.

What I’m going to build

To illustrate the approach, I’m going to build a simple component that displays a list of countries and allows the user to filter them by continent.

I’m using the restcountries  API to get the data.

Getting the data on the server

To fetch our data from the server, we're going to use SvelteKit load function. This function is first called on the server on the initial page load and then on the client when navigating to the page.

I wrote a blog post about load functions in SvelteKit here:

Since we need the data returned to be updated every time the user changes the filter, we need to "make it depends " on whatever we trigger on the client when the user changes the filter. In our case, we're going to use the URL query parameters.

code loading...

If you want to learn more about query parameters in SvelteKit, I also wrote a blog post about it here:

Our load function is pretty simple. It fetches the data from the API and returns it as a prop to the component.

We could have made it a bit more complete by adding some validation in case the user manually enters an invalid region in the URL. Think of something like:

code loading...

Displaying the data

Data table

Since we are returning the data from the server as a prop, we can now display it in our component.

code loading...

Quite straightforward. We just iterate over the list of countries and display them in a table.

Notice that we are not destructuring the  data  prop to use  countries  directly. This is because  data  itself is reactive (whenever it changes on the server, the component will update it). But  const { countries } = data  would not be reactive and would only be updated on the initial page load.

Using directly  data.countries  might be a bit verbose, but it spares us from having to create another reactive variable to keep track of the countries.

The select dropdown

Now that we have our data displayed let's add a dropdown to filter the countries by continent. This is where the fun begins.

code loading...

The important part here is the  handleRegionChange  function. It uses the  goto  function from SvelteKit to push a new URL with the new region as a query parameter. This is all we need to trigger a new server-side render and update the data.

Now, we can populate the select dropdown with the list of regions we created earlier and bind its value to the  selectedRegion  variable.

code loading...

And that's all we need.

Every time the user changes the region, the server will fetch the data from the API again, and the component will update. The reason why the server can re-fetch the data is because of how SvelteKit handles invalidation. If your load function depends on or references a property whose value has changed, the page will be invalidated, and the load function will be called again.

Note: Read more about invalidation in SvelteKit here:

Get help with your Svelte or SvelteKit code

Got a Svelte/Sveltekit bug giving you headaches? I’ve been there!

Book a free 15 min consultation call, and I’ll review your code base and give you personalized feedback on your code.

P.S. If you have a bigger problem that may need more than 15 minutes, you can also pick my brain for a small fee. 😊 But that’s up to you!


I like how SvelteKit makes it easy to handle reactive and stateful data. The approach is clean, simple, and very powerful.

You might also like these blog posts

A lovely bath

SvelteKit Internals: Load function

Discover how SvelteKit's load function simplifies data loading in your web app.

A lovely bath

Taking advantage of query parameters in SvelteKit

Master the art of query parameters in SvelteKit! Discover how to access and use them on both the client and server side with clear examples and explanations.