SkillByAIOpen interactive version →

Lesson 17 / 25

Load Functions: +page.ts vs +page.server.ts

Universal and server-only data loading.

Two kinds of load

A load function exported from +page.ts (or +layout.ts) is universal: it runs on the server during SSR and in the browser during client-side navigation, so it must not use secrets. A load in +page.server.ts runs only on the server, can access databases, private environment variables, cookies and locals, and its return value must be serialisable (SvelteKit uses devalue, so Dates, Maps and similar are supported). Both receive params, url and a fetch that works on both sides and forwards cookies. The page gets the merged result as data; types come from the generated ./$types (PageLoad, PageServerLoad, PageProps or PageData). Returning a promise that is not awaited lets slower data stream in later.

A server load and its page

Post detail with streamed comments.

// src/routes/blog/[slug]/+page.server.ts
import { error } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import { db } from '$lib/server/db';

export const load: PageServerLoad = async ({ params, locals }) => {
  const post = await db.post.findBySlug(params.slug);
  if (!post) error(404, 'Post not found');

  return {
    post,                                   // awaited: needed for first render
    comments: db.comment.listFor(post.id),  // not awaited: streams in later
    viewer: locals.user?.name ?? null
  };
};

// src/routes/blog/[slug]/+page.svelte
// <script lang="ts">
//   import type { PageProps } from './$types';
//   let { data }: PageProps = $props();
// </script>
// <h1>{data.post.title}</h1>
// {#await data.comments}<p>Loading comments...</p>{:then comments}
//   {#each comments as c (c.id)}<p>{c.body}</p>{/each}
// {/await}

Keep server code in $lib/server

SvelteKit refuses to import modules from src/lib/server (or files named *.server.ts) into code that runs in the browser, which protects secrets from leaking into client bundles.

Quick check: Where should a load function that queries the database with a secret key live?

  • In +page.svelte
  • In +page.ts
  • In +page.server.ts
  • In src/app.html
Answer

In +page.server.ts — Universal loads also run in the browser.