iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

load() Functions

SvelteKits load function runs on the server (and sometimes the client) before a page renders, fetching the data the page needs. It returns plain JSON and is bundled with the page during SSR for a single round trip. There are two flavours: +page.server.js for server-only loads (DB, secrets) and +page.js for isomorphic loads (public fetches).

Server load, client load, and form actions together

EXAMPLE
// src/routes/orders/+page.server.js — runs only on the server
import { error, redirect } from '@sveltejs/kit';

export async function load({ locals, url, depends }) {
  if (!locals.user) throw redirect(303, '/login');

  // Mark this load as depending on a custom invalidate key, so we can
  // re-run it after a form action without changing the URL.
  depends('app:orders');

  const status = url.searchParams.get('status') ?? 'open';
  const orders = await locals.db.orders.findAll({
    where: { customer_id: locals.user.id, status },
    orderBy: { created_at: 'desc' },
    limit: 25,
  });

  if (!orders) throw error(500, 'orders unavailable');

  return { orders, status };          // available as 'data' in the page
}

// Form actions live in the same file — fully typed, type-safe inputs
export const actions = {
  cancel: async ({ request, locals }) => {
    const data = await request.formData();
    const id = String(data.get('id') ?? '');
    if (!id) return { ok: false, message: 'missing id' };
    await locals.db.orders.update(id, { status: 'cancelled' });
    return { ok: true };
    // Returning here triggers SvelteKit to re-run any load() that
    // calls 'depends("app:orders")' — UI updates without a navigation.
  },
};

// ---- src/routes/orders/+page.svelte ----
<script>
  export let data;             // { orders, status }
  export let form;             // result of the last action

  import { enhance } from '$app/forms';
</script>

<h1>Orders ({data.status})</h1>

{#if form?.ok === false}
  <p class='error'>{form.message}</p>
{/if}

<ul>
  {#each data.orders as o}
    <li>
      #{o.id} — ${o.total} — {o.status}
      {#if o.status === 'open'}
        <form method='POST' action='?/cancel' use:enhance>
          <input type='hidden' name='id' value={o.id}>
          <button>Cancel</button>
        </form>
      {/if}
    </li>
  {/each}
</ul>

// ---- src/routes/+layout.js — isomorphic load (no secrets) ----
export async function load({ fetch }) {
  // 'fetch' here is SvelteKits enhanced fetch — works server & client
  const res = await fetch('/api/health');
  return { health: await res.json() };
}

Why it matters

Use +page.server.js whenever the load needs secrets, the database, or auth cookies — anything you would not want sent to the browser. Use +page.js (no .server) for public reads so the load can run on the client during client-side navigation, avoiding a round trip back to the server.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// +page.server.js
export async function load({ params }) {
    const user = await db.users.find(params.id);
    return { user };
}
Try it Yourself »

Discussion

Loading…