Loading Data
In this module, we will learn how to fetch and manipulate data before rendering the page using the load function.Course Version History
Nov. 21, 2022 - Updated to SvelteKit v1.0.0-next.549. Changed to the new
load
function API.
In the last module we learned how to create endpoints and fetch data from them. In the example we created, we fetch product data using the dynamic param, [name]
, of the page that we are on. While this works, there is a more convenient way to load data into a page using a sibling +page.js
file.
A +page.svelte
file can have a sibling +page.js
(or +page.ts
) that exports a load
function. The return value of this function is available to the page through the data
prop.
Let's create the new file /src/routes/product/[name]/+page.js
, which will export a load function like this:
export function load() {}
This will have the same functionality as the endpoint created in the last module, so we will use the dynamic name
param to find the product data in an array of products. Similar to our endpoint, the load function has access to dynamic parameters through the parameter params
. Let's use this to get our product name like this:
export function load({ params }) {
const productName = params.name;
}
Now, let's add a hard coded array of products, and use productName
to search this array and return the correct product.
export function load({ params }) {
const productName = params.product;
const product = products.find((product) => product.name === productName);
return {
product,
};
}
Finally, instead of fetching data from our endpoint in /src/routes/product/[name]/+page.svelte
, we can use the data
prop like this:
export let data;
let product = data.product;
Here we are exporting our prop, data
, making it available to our sibling +page.js
file where its value will be assigned. As soon as we route to this page, the load
function will automatically be called, and the value of data
will be set to the value returned from the load
function in +page.js
. We can then use this data
in +page.svelte
!
Testing this out in the browser, you will see the page has the same functionality using much less code!
We will learn more about how the load
function works later on in this module .The most important thing to know is that is runs on both the client and the server, unlike endpoints which only run on the server. This means that you should not use any sensitive information here. However, if your load
function should always run on the server (because it uses private environment variables, accesses a database, etc.) then you can put it in a +page.server.js
instead.
Layouts can also load data through +layout.js
or +layout.server.js
. It works the exact same way as pages, accessing the returned data through the data
prop. Any data returned from layout load
functions is also available to child +layout.svelte
components and the +page.svelte
component in addition to the layout that it belongs to. If multiple load
functions return data with the same key, the last one will take priority. For example, if we are using data.product
in a page where its layout returns {product: 'T-Shirt'}
and the page also returns {product: 'Cup'}
, then data.product
will be Cup
.
At this point we've learned that a +page.svelte
component, and each +layout.svelte
component above it, has access to its own data as well as all the data from its parents.
In some cases, we might need the opposite — a parent layout might need to access data from a page or a child layout. For example, the root layout might want to access the product
property returned from our load function in /src/routes/product/[name]/+page.js
. We can do this using $page.data
.
In our root layout, let's import page
. As we learned in the previous module on stores, we can reference a store value by prefixing the store name with a dollar sign. Let's log $page.data.product
like this:
import { page } from '$app/stores';
console.log($page.data.product);
Now, if we navigate to our product page, we see that our product object is logged in our layout!
As we've seen there are two types of load functions. +page.js
and +layout.js
files export load
functions that are shared between server and browser, while +page.server.js
and +layout.server.js
files export load
functions that are server-only. Conceptually, they're the same thing, but there are some key differences.
Both shared and server-only load functions have access to three properties (params
, route
, and url
) and various functions (depends
, fetch
, and parent
).
Server-only load
functions are called with a ServerLoadEvent
, which inherits clientAddress
, cookies
, locals
, platform
, and request
from RequestEvent
.
Shared load
functions are called with a LoadEvent
, which has a data
property. If you have load
functions in both +page.js
and +page.server.js
, the return value of the server-only load
function is the data
property of the shared load
function's argument.
A shared load
function can return an object containing any values, including things like custom classes and component constructors.
A server-only load
function must return data that can be serialized with devalue such as anything that can be represented as JSON or things like BigInt
, Date
, etc. — so that it can be transported over the network.
Now that we know the correct way to load data into our app using the load
function, in the next module we will learn how to prefetch our data to make our app feel extra snappy.
Was this helpful?