Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Loading data: the load function

A page usually needs data before it is shown: a list of posts, a user profile. In SvelteKit it is fetched with a load function that lives in a file next to +page.svelte. SvelteKit calls it before rendering the page and passes the result to the component.

A post store

No database yet — the posts live in an array. Create the file src/lib/server/posts.js:

// src/lib/server/posts.js
const posts = [
  { slug: 'hello-svelte', title: 'Hello, Svelte', body: 'Svelte is a UI compiler.' },
  { slug: 'runes', title: 'What runes are', body: 'Runes control reactivity.' }
];
 
export function getPosts() {
  return posts;
}
 
export function getPost(slug) {
  return posts.find((post) => post.slug === slug);
}
 
export function addPost(post) {
  posts.push(post);
}

The src/lib/server folder is special: modules from it can be imported only in server code. If you accidentally import such a module in a component, SvelteKit stops the build with an error, and secrets never reach the browser.

A server load function

Create src/routes/blog/+page.server.js next to the blog page:

// src/routes/blog/+page.server.js
import { getPosts } from '$lib/server/posts.js';
 
export function load() {
  return {
    posts: getPosts()
  };
}

The function returns an object — it becomes the page data. Code in +page.server.js runs only on the server, so here you can talk to a database and use secret keys.

Data in the component

The page receives the result of load in the data prop:

<!-- src/routes/blog/+page.svelte -->
<script>
  let { data } = $props();
</script>
 
<h1>Blog</h1>
<ul>
  {#each data.posts as post (post.slug)}
    <li><a href="/blog/{post.slug}">{post.title}</a></li>
  {/each}
</ul>

At http://localhost:5173/blog a list of two title links appears. The post pages themselves come in the lesson on dynamic routes.

A universal load function

A +page.js file (without .server) can also export load. It runs on the server when the page is first opened and in the browser during navigation. It is used to fetch data from an external API:

// src/routes/about/+page.js
export async function load({ fetch }) {
  const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
  return { author: await response.json() };
}

On the /about page the data is available as data.author.name. Use the fetch from the function argument, not the global one: SvelteKit forwards cookies and does not repeat the request in the browser after server rendering.

FileWhere it runsWhat for
+page.server.jsonly on the serverdatabase, secrets
+page.json the server and in the browserpublic APIs

Common mistake

Returning from a server load something that cannot be sent over the network: a function, a class instance with methods, a database connection. SvelteKit sends the data to the browser and reports an error about a non-serializable value. Return plain objects, arrays, strings, numbers and dates.

Thanks for reading!

Donate to the site — we work hard for you.