The Easy Way to Do Routing in Svelte
Most commonly an application comes with several pages, but unfortunately, Svelte doesn't have a built-in way to handle routing by default, so we are going to use a third-party community-developed package called svelte-routing. We are going to define all routes at the root of our application, App.svelte
.
If you don't have a Svelte app ready yet, you can bootstrap one using the command below:
npm create vite@latest myapp -- --template svelte
Implementing Routes in Svelte
First, make sure you install svelte-routing
into your project, by running npm i svelte-routing
. To define routes inside Svelte, we need to use the Router
and Route
components provided by svelte-routing
in our App.svelte
.
<script>
import { Router, Route } from 'svelte-routing'
import Home from './pages/Home.svelte'
import Details from './pages/Details.svelte'
</script>
<Router>
<Route component={Home} />
<Route path="/product/:id" let:params>
<Details id={params.id} />
</Route>
</Router>
In this example, we have two different pages. A homepage, and a product details page. First, we need to import the Router
and Route
components from svelte-routing
. For each route, we want to use the Route
component with a component
prop, where we can pass the component that we want to render. Notice that Route
components can only be used inside the Router
component.
For the home page, we just need to pass the component and we are good. However, for the Details
component, we want to define a path
prop as well. If the path matches the browser address, then this component gets rendered.
We can also define a dynamic path using the :id
annotation. This means that whatever comes after the path "product/", will be matched and stored inside the params.id
variable.
To expose the params object, make sure you define let:params
on the Route
component.
Let's take a closer look at how we can access the ID inside the Details
component.
Accessing Route Params in Svelte
Whenever someone navigates to /product/:id
, we want to find the correct product based on the passed ID in the location. To access the ID, we just need to export it as a prop:
<script>
export let id
// Here we can fetch the correct data from DB
// or find it among a list if its available in the state
const product = products.find(product => product.id)
</script>
details view for: {id}
However, If you navigate to a product page, you will notice that you can navigate to this page, even with IDs for non-existent products. To get around this, we can also do programmatic routing with the navigate
function.
Programmatic Routing in Svelte
To prevent navigation to the product page for non-existent products, we can use programmatic routing. The svelte-routing
library has a handy navigate
function we can call from our code in order to navigate to different pages, where using a link is not appropriate. Let's see how we can use this in our Details
component:
<script>
import { navigate } from 'svelte-routing'
export let id
const product = products.find(product => product.id)
if (!product) {
navigate('/')
}
</script>
details view for: {id}
If we don't find a product by the passed ID, we can navigate back to the home page using the navigate
function exposed by the svelte-routing
library.
We can also count for cases when no ID is passed. For this, we just need to add an additional Route
in our App.svelte
to match paths on the "/product" route without an ID.
<script>
import { Router, Route } from 'svelte-routing'
import Home from './pages/Home.svelte'
import Details from './pages/Details.svelte'
</script>
<Router>
<Route component={Home} />
<Route path="/product" component={Home} />
<Route path="/product/:id" let:params>
<Details id={params.id} />
</Route>
</Router>
This will ensure that we land back on the homepage if no ID is passed for the "/product" path.
Routing with the Link Component
There could be also cases where we want to trigger routing when a link is clicked. For this, we also have a special Link
component provided by svelte-routing
.
With this setup so far, you could only navigate through direct input in the address bar. However, we want to navigate to a product page whenever someone clicks on a link. To achieve this, we want to use the Link
component:
<script>
import { Link } from 'svelte-routing'
</script>
<nav>
<Link to="/">Home</Link>
<Link to="/product/1">Recommended Product</Link>
</nav>
Notice that, unlike regular anchors, this component has a to
prop as opposed to href
. This will ensure that a client-side navigation is triggered, instead of a full page reload.
Alternatively, we can also use a regular anchor tag with the use:link
action attached to the element, or use:links
attached to one of the parent elements. For example:
<script>
import { link, links } from 'svelte-routing'
</script>
<!-- using use:link on anchors -->
<a href="/" use:link>Home</a>
<a href="/details" use:link>Details</a>
<!-- using use:links on parent elements -->
<div use:links>
<a href="/">Home</a>
<a href="/details">Details</a>
</div>
Final Words
While Svelte doesn't have a built-in way to handle routing, the svelte-routing
library can cater to most use cases. In short, you can define routes using a Route
component inside a Router
, and you can navigate with:
navigate
: A function for programmatic navigation, where using a link is not appropriateLink
: A component to use in place of regular anchors for client-side navigationuse:link
: An action to be used on regular anchors to make it behave like aLink
componentuse:links
: An action used on wrappers to make all childen anchors behave likeLink
components.
Want to learn more about Svelte? Check out our introductory tutorial below! Thank you for reading through, happy coding! π¨βπ»
Rocket Launch Your Career
Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies: