Skip to main content
Svelte & SvelteKit·Lesson 3 of 5

SvelteKit Routing & Layouts

SvelteKit is the full-stack framework built on top of Svelte. It adds file-based routing, server-side rendering, API endpoints, and adapters for deployment — all with zero configuration.

Create a Project

npm create svelte@latest my-app
cd my-app
npm install
npm run dev

Choose "Skeleton project" → TypeScript (optional) → ESLint + Prettier.

File-Based Routing

Routes live in src/routes/. The file name determines the URL:

src/routes/
├── +page.svelte           /
├── +layout.svelte         shared wrapper for all routes
├── about/
   └── +page.svelte       /about
├── blog/
   ├── +page.svelte       /blog
   └── [slug]/
       └── +page.svelte   /blog/:slug
└── api/
    └── users/
        └── +server.js     /api/users  (API endpoint)

+ prefix is how SvelteKit distinguishes route files from regular components.

Pages

<!-- src/routes/+page.svelte -->
<h1>Welcome Home</h1>
<p>This is the home page.</p>
<a href="/about">About</a>

Use plain <a> tags — SvelteKit intercepts clicks and navigates client-side.

Layouts

+layout.svelte wraps every page in its directory and its subdirectories:

<!-- src/routes/+layout.svelte -->
<script>
  import Nav from '$lib/Nav.svelte';
</script>

<Nav />
<main>
  <slot />  <!-- page content goes here -->
</main>
<footer>© 2026 My Site</footer>

Nested layouts compose — a /blog/[slug] page gets both the root layout and any /blog/+layout.svelte.

Load Functions

Fetch data on the server before the page renders using a +page.server.js (server-only) or +page.js (server + client):

// src/routes/blog/+page.server.js
export async function load({ fetch }) {
  const res   = await fetch('/api/posts');
  const posts = await res.json();
  return { posts };  // available as data.posts in the page
}
<!-- src/routes/blog/+page.svelte -->
<script>
  export let data;  // injected by SvelteKit
</script>

{#each data.posts as post}
  <a href="/blog/{post.slug}">{post.title}</a>
{/each}

Route Parameters

// src/routes/blog/[slug]/+page.server.js
export async function load({ params, fetch }) {
  const res  = await fetch(`/api/posts/${params.slug}`);
  if (!res.ok) throw error(404, 'Post not found');
  return { post: await res.json() };
}

params.slug matches [slug] in the folder name.

What a SvelteKit Page Looks Like

SvelteKit renders HTML → the browser receives fully rendered content then hydrates. Here's a static version of what the output looks like:

Ctrl+Enter
HTML
CSS
JS
Preview

API Routes

Create a +server.js file to build a REST endpoint:

// src/routes/api/users/+server.js
import { json } from '@sveltejs/kit';

export async function GET() {
  const users = await db.query('SELECT * FROM users');
  return json(users);
}

export async function POST({ request }) {
  const body = await request.json();
  const user = await db.create(body);
  return json(user, { status: 201 });
}