Skip to main content

To match an unknown number of path segments, use a [...rest] parameter, so named for its resemblance to rest parameters in JavaScript.

Rename src/routes/[path] to src/routes/[...path]. The route now matches any path.

Other, more specific routes will be tested first, making rest parameters useful as ‘catch-all’ routes. For example, if you needed a custom 404 page for pages inside /categories/..., you could add these files:

src/routes/
├ categories/
│ ├ animal/
│ ├ mineral/
│ ├ vegetable/
│ ├ [...catchall]/
│ │ ├ +error.svelte
│ │ └ +page.server.js

Inside the +page.server.js file, error(404) inside load.

Rest parameters do not need to go at the end — a route like /items/[...path]/edit or /items/[...path].json is totally valid.

Edit this page on GitHub

<script>
import { page } from '$app/stores';

let words = ['how', 'deep', 'does', 'the', 'rabbit', 'hole', 'go'];

let depth = $derived($page.params.path.split('/').filter(Boolean).length);
let next = $derived(depth === words.length ? '/' : `/${words.slice(0, depth + 1).join('/')}`);
</script>

<div class="flex">
{#each words.slice(0, depth) as word}
<p>{word}</p>
{/each}

<p><a href={next}>{words[depth] ?? '?'}</a></p>
</div>

<style>
.flex {
display: flex;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
}

p {
margin: 0.5rem 0;
line-height: 1;
}

a {
display: flex;
width: 100%;
height: 100%;
align-items: center;