Skip to main content
Svelte Fundamentals
CHAPTER 13 Beginner

Routing in Svelte

Updated: May 18, 2026
5 min read

# CHAPTER 13

Routing in Svelte

1. Chapter Introduction

A Single Page Application needs to display different views based on the URL without reloading the page. For plain Svelte (without SvelteKit), the popular svelte-spa-router library provides a clean, declarative routing solution. For full-stack apps, SvelteKit's file-based routing is covered in the next chapter.

2. Learning Objectives

  • Install and configure svelte-spa-router.
  • Define routes and link between pages.
  • Read route parameters.
  • Implement a 404 page and redirect logic.
  • Build a multi-page Svelte app.

3. Installing svelte-spa-router

bash
1
npm install svelte-spa-router

4. Setting Up Routes

javascript
1234567891011121314
// src/routes.js
import Home from './routes/Home.svelte';
import About from './routes/About.svelte';
import ProductList from './routes/ProductList.svelte';
import ProductDetail from './routes/ProductDetail.svelte';
import NotFound from './routes/NotFound.svelte';

export const routes = {
  '/': Home,
  '/about': About,
  '/products': ProductList,
  '/products/:id': ProductDetail,  // Dynamic route parameter
  '*': NotFound  // 404 catch-all
};
svelte
1234567891011
<!-- App.svelte -->
<script>
  import Router from &#039;svelte-spa-router';
  import { routes } from &#039;./routes.js';
  import Navbar from &#039;./lib/Navbar.svelte';
</script>

<Navbar />
<main>
  <Router {routes} />
</main>
svelte
12345678910111213141516
<!-- Navbar.svelte -->
<script>
  import { Link } from &#039;svelte-spa-router';
  import { link, active } from &#039;svelte-spa-router';
</script>

<nav>
  <!-- Using Link component -->
  <Link to="/">Home</Link>
  <Link to="/products">Products</Link>
  <Link to="/about">About</Link>

  <!-- Using href with the link action -->
  <a href="/" use:link>Home</a>
  <a href="/products" use:link>Products</a>
</nav>
svelte
123456789101112131415
<!-- Programmatic navigation -->
<script>
  import { push, pop, replace } from &#039;svelte-spa-router';

  function goToProducts() {
    push(&#039;/products');
  }

  function goBack() {
    pop();
  }
</script>

<button on:click={goToProducts}>View Products</button>
<button on:click={goBack}>← Back</button>

6. Route Parameters

svelte
12345678910111213141516171819202122232425262728
<!-- routes/ProductDetail.svelte -->
<script>
  import { onMount } from &#039;svelte';

  export let params = {}; // svelte-spa-router passes params here

  let product = null;
  let loading = true;

  $: productId = params.id;

  onMount(async () => {
    const res = await fetch(`https://fakestoreapi.com/products/${productId}`);
    product = await res.json();
    loading = false;
  });
</script>

{#if loading}
  <p>Loading product #{productId}...</p>
{:else if product}
  <div class="product-detail">
    <img src={product.image} alt={product.title} />
    <h1>{product.title}</h1>
    <p>${product.price}</p>
    <p>{product.description}</p>
  </div>
{/if}

7. Mini Project: Multi-Page App Structure

text
123456789101112
src/
├── routes/
│   ├── Home.svelte
│   ├── Products.svelte
│   ├── ProductDetail.svelte
│   ├── About.svelte
│   └── NotFound.svelte
├── lib/
│   ├── Navbar.svelte
│   └── Footer.svelte
├── routes.js
└── App.svelte
svelte
12345678910
<!-- routes/NotFound.svelte -->
<script>
  import { push } from &#039;svelte-spa-router';
</script>

<div class="not-found">
  <h1>404 — Page Not Found</h1>
  <p>The page you are looking for does not exist.</p>
  <button on:click={() => push(&#039;/')}>Go Home</button>
</div>
svelte
12345678910111213141516
<script>
  import { location } from &#039;svelte-spa-router';
</script>

<nav>
  {#each [{path:'/', label:'Home'}, {path:'/products', label:'Products'}] as route}
    <a
      href={route.path}
      class:active={$location === route.path}
    >{route.label}</a>
  {/each}
</nav>

<style>
  .active { color: #ff3e00; font-weight: bold; border-bottom: 2px solid #ff3e00; }
</style>

9. Common Mistakes

  • Forgetting hash-based URLs: svelte-spa-router uses hash-based routing by default (/#/products). For clean URLs (/products), use SvelteKit instead.
  • Not handling the 404 route: Always add a '*': NotFound catch-all route.

10. MCQs

Question 1

What library enables client-side routing in plain Svelte?

Question 2

What is a dynamic route parameter?

Question 3

Where does svelte-spa-router inject the matching component?

Question 4

What function navigates to a route programmatically?

Question 5

What route pattern matches all unmatched routes?

Question 6

How do route parameters arrive in a route component?

Question 7

What store exposes the current URL path?

Question 8

What type of URLs does svelte-spa-router use by default?

Question 9

What SvelteKit feature replaces client-side routers for Svelte?

Question 10

How do you navigate back one step?

11. Interview Questions

  • Q: What is the difference between hash-based and history-based routing?
  • Q: When would you choose plain Svelte with svelte-spa-router versus SvelteKit?

12. Summary

svelte-spa-router provides a lightweight, declarative routing solution for Svelte SPAs. For production applications requiring SSR, file-based routing, and server endpoints, SvelteKit (covered next) is the preferred solution.

13. Next Chapter Recommendation

In
Chapter 14: SvelteKit Basics**, we explore Svelte's full-stack framework with file-based routing, server-side rendering, layouts, and API endpoints.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·