Sapper
01 / 02

Routing, SSR & Data Loading (Legacy)

Sapper: Routing, SSR & Data Loading (Legacy)

⚠ Sapper is deprecated and fully superseded by SvelteKit. Do not start a new project with it. This page exists for maintaining or migrating an existing Sapper codebase, and for understanding SvelteKit's design lineage.

Sapper was Svelte's original application framework -- Svelte provides the component compiler; Sapper added the app-level layer (filesystem routing, SSR, code-splitting, build tooling) on top, the same relationship Next.js has to React.

Filesystem Routing

src/routes/
  index.svelte           -> /
  about.svelte            -> /about
  blog/
    index.svelte           -> /blog
    [slug].svelte           -> /blog/:slug  (dynamic segment)
  api/
    posts.js                -> server route, not a page
  _layout.svelte           -> shared wrapper (nav/footer) around sibling pages
  _error.svelte            -> custom error page (404, thrown errors)

// SvelteKit continued this filesystem-routing idea but revised the
// specific file-naming conventions -- a Sapper-to-SvelteKit migration
// wasn't a pure rename, it required adjusting file structure and APIs.

preload(): Fetching Page Data

<script context="module">
  // Runs on the SERVER for the initial request, and on the CLIENT
  // for subsequent client-side navigations -- isomorphic data loading
  export async function preload({ params, query }) {
    const res = await this.fetch(`/api/posts/${params.slug}`);
    const post = await res.json();
    return { post }; // becomes a prop on the component below
  }
</script>

<script>
  export let post;
</script>

<h1>{post.title}</h1>

<!-- SvelteKit's `load` function is the direct conceptual successor -->

Server Routes (API Endpoints)

// src/routes/api/posts.js -- colocated with page routes, same
// filesystem convention, exports handlers per HTTP method
export async function get(req, res) {
  const posts = await db.posts.findAll();
  res.setHeader('Content-Type', 'application/json');
  res.end(JSON.stringify(posts));
}

export async function post(req, res) {
  const created = await db.posts.create(req.body);
  res.writeHead(201, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify(created));
}

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free