Svelte and SvelteKit course Β· Module 11: SvelteKit Routing

Drakkar - SvelteKit Routing

2 min read Β·
In this lesson5

Welcome to the port of Hedeby! The Viking drakkars are ready for the great voyage. SvelteKit is our ship for building full fullstack applications!

What is SvelteKit?

SvelteKit is a fullstack framework for Svelte:

  • File-based routing
  • SSR, SSG, CSR
  • API routes
  • Form actions

In this part of the world we sail with SvelteKit 3 and Svelte 5.

A new project

npx sv create my-voyage
cd my-voyage
npm run dev

The sv wizard asks about the template and add-ons (for example TypeScript). SvelteKit configuration, including the adapter, lives in vite.config.js - SvelteKit 3 no longer has a separate svelte.config.js file.

Directory structure

src/
β”œβ”€β”€ routes/
β”‚   β”œβ”€β”€ +page.svelte        # /
β”‚   β”œβ”€β”€ +layout.svelte      # Layout for all pages
β”‚   β”œβ”€β”€ about/
β”‚   β”‚   └── +page.svelte    # /about
β”‚   β”œβ”€β”€ warriors/
β”‚   β”‚   β”œβ”€β”€ +page.svelte    # /warriors
β”‚   β”‚   └── [id]/
β”‚   β”‚       └── +page.svelte # /warriors/123
β”‚   └── api/
β”‚       └── warriors/
β”‚           └── +server.js   # /api/warriors
β”œβ”€β”€ lib/                     # Shared code, imported via #lib
β”‚   └── components/
└── app.html
vite.config.js               # Vite and SvelteKit configuration

Basic page

<!-- src/routes/+page.svelte -->
<script>
  let name = 'Viking';
</script>

<h1>Welcome, {name}!</h1>
<a href="/warriors">See warriors</a>

A plain <a href> link is all you need to go to another page. SvelteKit intercepts the click and swaps the page without reloading the browser.

<script>
  import { goto } from '$app/navigation';

  function goToWarriors() {
    goto('/warriors');
  }
</script>

<!-- Link -->
<a href="/warriors">Warriors</a>

<!-- Programmatic navigation -->
<button onclick={goToWarriors}>Go to warriors</button>

The drakkar is ready - we sail through SvelteKit routing!

Code for this lesson: App.svelte
<script>
  // Drakkar - Navigating the SvelteKit seas
  // Routing structure simulation

  let currentPath = $state('/');

  const routes = [
    { path: '/', name: 'Home page', icon: '' },
    { path: '/warriors', name: 'Warriors', icon: '' },
    { path: '/warriors/ragnar', name: 'Ragnar', icon: '' },
    { path: '/ships', name: 'Ships', icon: '' },
    { path: '/about', name: 'About us', icon: 'β„Ή' }
  ];

  function navigate(path) {
    currentPath = path;
  }
</script>

<main class="drakkar">
  <h1>Drakkar - SvelteKit Routing</h1>

  <section class="structure">
    <h2>Folder structure</h2>
    <pre>
src/routes/
β”œβ”€β”€ +page.svelte          β†’ /
β”œβ”€β”€ +layout.svelte        β†’ Layout
β”œβ”€β”€ warriors/
β”‚   β”œβ”€β”€ +page.svelte      β†’ /warriors
β”‚   └── [id]/
β”‚       └── +page.svelte  β†’ /warriors/:id
β”œβ”€β”€ ships/
β”‚   └── +page.svelte      β†’ /ships
└── about/
    └── +page.svelte      β†’ /about
    </pre>
  </section>

  <nav class="nav">
    {#each routes as route}
      <button
        class:active={currentPath === route.path}
        onclick={() => navigate(route.path)}
      >
        {route.icon} {route.name}
      </button>
    {/each}
  </nav>

  <section class="content">
    <h2>Current path: {currentPath}</h2>

    {#if currentPath === '/'}
      <p>Welcome to the land of Vikings!</p>
    {:else if currentPath === '/warriors'}
      <p>List of all warriors</p>
    {:else if currentPath === '/warriors/ragnar'}
      <p>Warrior profile: Ragnar Lothbrok</p>
    {:else if currentPath === '/ships'}
      <p>Our Drakkar fleet</p>
    {:else if currentPath === '/about'}
      <p>About our clan</p>
    {/if}
  </section>
</main>

<style>
  .drakkar {
    font-family: 'Georgia', serif;
    max-width: 600px;
    margin: 0 auto;
    padding: 2rem;
    background: #0a1628;
    color: #b8d4f7;
    min-height: 100vh;
  }

  h1 {
    color: #4a90d9;
    text-align: center;
  }

  section {
    background: rgba(74, 144, 217, 0.1);
    border: 1px solid #4a90d9;
    border-radius: 8px;
    padding: 1rem;
    margin: 1rem 0;
  }

  h2 {
    color: #4a90d9;
    font-size: 1rem;
    margin-top: 0;
  }

  pre {
    background: rgba(0,0,0,0.5);
    padding: 1rem;
    border-radius: 4px;
    font-size: 0.85rem;
    overflow-x: auto;
  }

  .nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 1rem 0;
  }

  button {
    padding: 0.5rem 1rem;
    background: #1e3a5f;
    color: #b8d4f7;
    border: 1px solid #4a90d9;
    border-radius: 4px;
    cursor: pointer;
  }

  button.active {
    background: #4a90d9;
    color: #0a1628;
  }

  .content {
    min-height: 100px;
  }
</style>

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. How does SvelteKit determine routing?

Hands-on tasks in the game

  • Code editor

    Complete the navigation code

Useful articles