# Load Functions: +page.ts vs +page.server.ts — Svelte / SvelteKit

Source: https://www.skillbyai.com/en/svelte/k-load

> 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.

```typescript
// 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.

**Quiz:** Where should a load function that queries the database with a secret key live?

- [ ] In +page.svelte
- [ ] In +page.ts
- [x] In +page.server.ts
- [ ] In src/app.html

*Answer:* In +page.server.ts. Universal loads also run in the browser.
