Advanced routing
Edit this page on GitHubRest parameterspermalink
If the number of route segments is unknown, you can use rest syntax — for example you might implement GitHub's file viewer like so...
/[org]/[repo]/tree/[branch]/[...file]...in which case a request for /sveltejs/kit/tree/master/documentation/docs/04-advanced-routing.md would result in the following parameters being available to the page:
ts{org: 'sveltejs',repo : 'kit',branch : 'master',file : 'documentation/docs/04-advanced-routing.md'}
This also allows you to render custom 404s. Given these routes...
src/routes/
├ marx-brothers/
│ ├ chico/
│ ├ harpo/
│ ├ groucho/
│ └ +error.svelte
└ +error.svelte...the marx-brothers/+error.svelte file will not be rendered if you visit /marx-brothers/karl, because no route was matched. If you want to render the nested error page, you should create a route that matches any /marx-brothers/* request, and return a 404 from it:
src/routes/
├ marx-brothers/
| ├ [...path]/
│ ├ chico/
│ ├ harpo/
│ ├ groucho/
│ └ +error.svelte
└ +error.svelte
src/routes/a/[...rest]/z/+page.sveltewill match/a/z(i.e. there's no parameter at all) as well as/a/b/zand/a/b/c/zand so on. Make sure you check that the value of the rest parameter is valid, for example using a matcher.
Matchingpermalink
A route like src/routes/archive/[page] would match /archive/3, but it would also match /archive/potato. We don't want that. You can ensure that route parameters are well-formed by adding a matcher — which takes the parameter string ("3" or "potato") and returns true if it is valid — to your params directory...
src/params/integer.js
tsexport functionmatch (param ) {return /^\d+$/.test (param );}
...and augmenting your routes:
src/routes/archive/[page]
src/routes/archive/[page=integer]
If the pathname doesn't match, SvelteKit will try to match other routes (using the sort order specified below), before eventually returning a 404.
Matchers run both on the server and in the browser.
Sortingpermalink
It's possible for multiple routes to match a given path. For example each of these routes would match /foo-abc:
src/routes/[...catchall]/+page.svelte
src/routes/[a]/+server.js
src/routes/[b]/+page.svelte
src/routes/foo-[c]/+page.svelte
src/routes/foo-abc/+page.svelteSvelteKit needs to know which route is being requested. To do so, it sorts them according to the following rules...
- More specific routes are higher priority (e.g. a route with no parameters is more specific than a route with one dynamic parameter, and so on)
+serverfiles have higher priority than+pagefiles- Parameters with matchers (
[name=type]) are higher priority than those without ([name]) - Rest parameters have lowest priority
- Ties are resolved alphabetically
...resulting in this ordering, meaning that /foo-abc will invoke src/routes/foo-abc/+page.svelte, and /foo-def will invoke src/routes/foo-[c]/+page.svelte rather than less specific routes:
src/routes/foo-abc/+page.svelte
src/routes/foo-[c]/+page.svelte
src/routes/[a]/+server.js
src/routes/[b]/+page.svelte
src/routes/[...catchall]/+page.svelteEncodingpermalink
Directory names are URI-decoded, meaning that (for example) a directory like %40[username] would match characters beginning with @:
tsassert .equal (decodeURIComponent ('%40[username]'),'@[username]');
To express a % character, use %25, otherwise the result will be malformed.
Named layoutspermalink
Some parts of your app might need something other than the default layout. For these cases you can create named layouts...
src/routes/+layout-foo.svelte
<div class="foo">
<slot></slot>
</div>...and then use them by referencing the layout name (foo, in the example above) in the filename:
src/routes/my-special-page/+page@foo.svelte
<h1>I am inside +layout-foo</h1>Named layout should only be referenced from Svelte files
Named layouts are very powerful, but it can take a minute to get your head round them. Don't worry if this doesn't make sense all at once.
Scopingpermalink
Named layouts can be created at any depth, and will apply to any components in the same subtree. For example, +layout-foo will apply to /x/one and /x/two, but not /x/three or /four:
src/routes/
├ x/
│ ├ +layout-foo.svelte
│ ├ one/+page@foo.svelte # ✅ page has `@foo`
│ ├ two/+page@foo.svelte # ✅ page has `@foo`
│ └ three/+page.svelte # ❌ page does not have `@foo`
└ four/+page@foo.svelte # ❌ page has `@foo`, but +layout-foo is not 'in scope'Inheritance chainspermalink
Layouts can themselves choose to inherit from named layouts, from the same directory or a parent directory. For example, x/y/+layout@root.svelte is the default layout for /x/y (meaning /x/y/one, /x/y/two and /x/y/three all inherit from it) because it has no name. Because it specifies @root, it will inherit directly from the nearest +layout-root.svelte, skipping +layout.svelte and x/+layout.svelte.
src/routes/
├ x/
│ ├ y/
│ │ ├ +layout@root.svelte
│ │ ├ one/+page.svelte
│ │ ├ two/+page.svelte
│ │ └ three/+page.svelte
│ └ +layout.svelte
├ +layout.svelte
└ +layout-root.svelteIn the case where
+layout-root.sveltecontains a lone<slot />, this effectively means we're able to 'reset' to a blank layout for any page or nested layout in the app by adding@root.
If no parent is specified, a layout will inherit from the nearest default (i.e. unnamed) layout above it in the tree. In some cases, it's helpful for a named layout to inherit from a default layout alongside it in the tree, such as +layout-root.svelte inheriting from +layout.svelte. We can do this by explicitly specifying @default, allowing /x/y/one and siblings to use the app's default layout without using x/+layout.svelte:
src/routes/
├ x/
│ ├ y/
│ │ ├ +layout@root.svelte
│ │ ├ one/+page.svelte
│ │ ├ two/+page.svelte
│ │ └ three/+page.svelte
│ └ +layout.svelte
├ +layout.svelte
└ +layout-root.svelte
└ +layout-root@default.svelte
defaultis a reserved name — in other words, you can't have a+layout-default.sveltefile.