Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/jpcutshall/svelte5-router/llms.txt

Use this file to discover all available pages before exploring further.

svelte5-router is a declarative routing library built for Svelte 5. You wrap your application in a <Router> component that acts as a context provider, declare <Route> components to map URL paths to views, and use <Link> components to navigate between them — no imperative configuration required.

Installation

Install the package as a dev dependency:
npm i -D svelte5-router

Setting Up Your First Router

The Router component supplies routing context to all Link and Route descendants. Every Svelte 5 app needs at least one Router at the top of the component tree.
1

Import the core components

Bring in Router, Route, and Link from svelte5-router, along with the page components you want to render.
App.svelte
<script>
  import { Router, Link, Route } from "svelte5-router";
  import Home from "./routes/Home.svelte";
  import About from "./routes/About.svelte";
  import Blog from "./routes/Blog.svelte";

  let url = $state("");
</script>
Declaring let url = $state("") is the recommended pattern. A falsy value is ignored in the browser but lets you pass a real URL during SSR. See the SSR guide for details.
2

Wrap your layout in Router

Pass the url prop to Router. Inside it, add navigation links and your route declarations.
App.svelte
<Router {url}>
  <nav>
    <Link to="/">Home</Link>
    <Link to="/about">About</Link>
    <Link to="/blog">Blog</Link>
  </nav>

  <main>
    <Route path="/blog" component={Blog} />
    <Route path="/about" component={About} />
    <Route path="/"><Home /></Route>
  </main>
</Router>
3

Mount the app

Use Svelte 5’s mount function in your entry point. No special router setup is needed here.
main.ts
import App from "./App.svelte";
import { mount } from "svelte";

const app = mount(App, {
  target: document.getElementById("app")!,
});

export default app;

Route Path Matching

Each <Route path="..."> is evaluated against the current URL’s pathname. The router scores every registered route and renders the highest-scoring match.

How Scoring Works

The router uses a segment-based scoring system so you never need to worry about declaration order. Every segment starts with a base of 4 points (SEGMENT_POINTS), then an additional bonus or penalty is applied based on the segment type:
Segment typeCalculationScore per segment
Static (e.g. about)4 (SEGMENT_POINTS) + 3 (STATIC_POINTS)7
Dynamic (e.g. :id)4 (SEGMENT_POINTS) + 2 (DYNAMIC_POINTS)6
Root ("")4 (SEGMENT_POINTS) + 1 (ROOT_POINTS)5
Wildcard (*)4 (SEGMENT_POINTS) − 4 − 1 (SPLAT_PENALTY)−1
This means static > dynamic > root > splat. A route like /blog/:id will always beat /blog/* for a URL like /blog/42.

The Default (Fallback) Route

A <Route> with no path prop (or path="") acts as the fallback that matches when no other route does. Use this for 404 pages or catch-all layouts.
<Router {url}>
  <Route path="/about" component={About} />
  <Route path="/blog" component={Blog} />

  <!-- Renders when nothing else matches -->
  <Route component={NotFound} />
</Router>

Complete Working Example

The example below mirrors the structure used in the library’s own dev app, with Home, About, and Blog routes:
<script>
  import { Router, Link, Route } from "svelte5-router";
  import Home from "./routes/Home.svelte";
  import About from "./routes/About.svelte";
  import Blog from "./routes/Blog.svelte";
  import BlogPost from "./routes/BlogPost.svelte";
  import NotFound from "./routes/NotFound.svelte";

  let url = $state("");
</script>

<Router {url}>
  <nav>
    <Link to="/">Home</Link>
    <Link to="/about">About</Link>
    <Link to="/blog">Blog</Link>
  </nav>

  <main>
    <Route path="/blog/:id" component={BlogPost} />
    <Route path="/blog" component={Blog} />
    <Route path="/about" component={About} />
    <Route path="/"><Home /></Route>
    <Route component={NotFound} />
  </main>
</Router>
<Link> renders a standard <a> element that pushes onto the browser history stack. It accepts all standard anchor attributes plus a few routing-specific ones.
PropDefaultDescription
to"#"The URL to navigate to
replacefalseReplace the history entry instead of pushing a new one
state{}Object pushed to the history state
preserveScrollfalsePrevent the page from scrolling to the top after navigation
Link exposes an active boolean to its children snippet. Use this to style the currently active link — for example, by passing it into a custom menu item component.
<Link to="/about">
  {#snippet children(active)}
    <MenuItem active={active}>About</MenuItem>
  {/snippet}
</Link>
The active value is true when the link’s href exactly matches the current pathname (aria-current="page" is also set automatically).
You can use the link and links Svelte actions as an alternative to the <Link> component when you want to progressively enhance plain <a> tags. See the link action and links action API reference for details.

Rendering Children Directly in Route

Instead of passing a component prop, you can render children directly inside <Route>. This is useful when you need to pass explicit static props:
<Route path="/">
  <Home greeting="Hello, world!" />
</Route>
Both approaches are equivalent for simple cases. Use the component prop when you want the router to spread URL parameters directly onto the component as props (covered in Dynamic Routes).

Build docs developers (and LLMs) love