Exploring Data Fetching in SvelteKit's latest version

Exploring Data Fetching in SvelteKit's latest version

Written by jeblister on Mar 4th, 2023 ・ Views ・ Report Post

In this article, we'll examine how to fetch data in SvelteKit's latest version, including methods to fix any issues caused by the breaking changes. We'll discuss the fundamentals to help you get your SvelteKit applications up and running. All of these processes are essential.

What is SvelteKit?

SvelteKit is the most recent version of the popular Svelte framework. It provides an intuitive design language and user-friendly syntax to help developers create modern web applications. Unlike other frameworks, SvelteKit is easy to learn, as it requires minimal coding knowledge.

How to Fetch Data

To understand how to load data within a Sveltkit application, let's review the Sveltkit documentation.

Before a +page.svelte component (and its containing +layout.svelte components) can be rendered, we often need to get some data. This is done by defining load functions.

+page.svelte obtains data from a load function, which can be defined in either +page.ts (running both server and browser) or +page.server.ts (only running server, allowing access to private environment variables and database calls). Regardless of which file is used, the load function must return an object which becomes the data passed into the page component.

And I've actually set up a few example pages to demonstrate some of these concepts.

The data you load from the load function should be exported and can be imported by other pages. This allows you to abstract the actual source of data for each page, which makes your application easier to manage and maintain.

To load data into a Sveltkit page, you need to define a load function inside your page’s typescript file. The load function can be asynchronous, meaning that it can return a Promise or take a callback. Once the data is fetched, it can be exported from the page file to be used by other pages.

Using the +page.ts file

src/routes/shop/+page.ts
import type { PageLoad } from './$types';

export const load = (async ({ fetch }) => {
	const fetchProducts = async () => {
		const productRes = await fetch('https://dummyjson.com/products?limit=10');
		const productData = await productRes.json();
		return productData.products;
	};

	return {
		products: fetchProducts()
	};
}) satisfies PageLoad;

As the documentation said, a +page.svelte receives its data from a load function which is defined inside of a +page.ts file. So that means whatever we return here should get passed into +page.svelte.

So we're going to be using the dummy Json API to get some dummy or fake Json data.

The dummy Json API has a ton of different endpoints, but the one we are going to be using is the one that returns a list of products. This endpoint returns an array of dummy products, each with a title, description, and price.

Using this endpoint, our goal is to get the list of products and render them on the page.

  • First, we will need to make an AJAX request to the endpoint and get the data from the response. We can use SvelteKit’s special version fetch that is available in load functions. We can use the GET request to retrieve the dummy products from the endpoint. We then use the .json() method to get the response data.
  • We will use the return statement to return an object that has the products from our AJAX request. This is what will be passed into our +page.svelte for us to use.
src/routes/shop/+page.svelte
<script lang="ts">
	import type { PageData } from './$types';

	export let data: PageData;
	$: ({ products } = data);
</script>

<h1>Products</h1>
{#each products as product}
	<ul><li><h1>{product.title}</h1></li></ul>
{/each}

Now, in our +page.svelte we’re able to iterate through the products and render them on the page. We can also use product data to create more complex components and show different types of data.

Notice how we accepted a data prop, and how we destructure some variables from that prop.

⚠️ You need to wrap the whole thing in parentheses to destructure variables when you aren’t declaring them at the same time, and so this is it works in Svelte.

Using the +page.server.ts file

Finally, let's look at fetching data with the `+page.server.ts` file.

The +page.server.ts file only runs server-side and has access to private environment variables (such as API keys). Since +page.server.ts is only run on the server, it can make API calls to the database or any other service outside of the browser.

Using the +page.server.ts file for data fetching can help keep your API keys secure, since they won't be exposed in the browser.

When using +page.server.ts, you can define a load function that looks very similar to the one in `+page.ts`. Just remember that the `load` function should return an object that gets passed into the page component.

src/routes/movies/+page.server.ts
import type { PageServerLoad } from './$types';
import {TMDB_API_KEY} from '$env/static/private';

export const load = (async () => {

    const fetchMovies = async () => {
        const res = await fetch(`https://api.themoviedb.org/3/trending/movie/week?api_key=${TMDB_API_KEY}`)
        const data = await res.json()
        return data.results
    }

    return {
        movies: fetchMovies(),
    }
}) satisfies PageServerLoad;
  • We do have it defined as an environment variable as well that we're going to be able to pull into our page server.
  • We just use regular node fetch for this. But I do need to import the environment variable.
  • The $env/static/private and $env/dynamic/private modules can only be imported into modules that only run on the server, such as hooks.server.js or +page.server.js.
  • Now we need to return the object that will get passed into the page component. So we're going to return an object with movies, and the movies will fetch movies that we just created.

The +page.server.ts allows us to securely obtain data while also abstracting the source of data. We can write our +page.server.ts to use a service like a database, API, or any other source of data, while the +page.svelte file can remain unaware of the source of data.

Potential Issues

SvelteKit's newest version might cause some issues when fetching data. The most common issues occur when developers forget to use `await` to wait for fetch requests to be completed. The use of `async` is also essential, as it will help ensure that the `fetch` hook performs its tasks properly.

Moreover, developers must ensure that the response data is properly returned from the server. The data should be explicitly returned from the promise resolved by the `fetch` hook. This will ensure that the data is properly handled and parsed on the client side.

Another issue that can cause problems is the lack of SSL certificates from the server. Without the proper certificates, the browser will refuse to make any requests, resulting in an error. To ensure that this does not happen, developers must make sure that their server is properly configured to use SSL certificates.

Conclusion

Fetching data in SvelteKit's latest version is an essential part of web development. Developers must take into account all the issues that might arise due to the changes in the framework as well as the security of the server. With proper planning and execution, these processes can be made much easier and faster.

If you have any questions. Feel free to ask me any questions you may have.

PS: Check out the video SvelteKit Dynamic Routes & Slugs with Route Params for a more visual and detail explanation.

Comments (0)