How to Set Up Protected Routes in Your Svelte Application

How to Set Up Protected Routes in Your Svelte Application

Authenticate your users to access your routes
Ferenc Almasi β€’ Last updated 2021 July 13 β€’ Read time 7 min read
Learn how you can utilize the svelte-routing library to implement custom private routes in your Svelte application that requires authentication.
  • twitter
  • facebook

Svelte has taken the world by storm since its version 3 release in 2019, and it’s growing in popularity. Since then, many Svelte libraries have popped up, one of them is svelte-routing, which provides easy means to create routes in a similar manner to React.

In this tutorial, we are going to take a look at how you can use it to create protected routes to prevent unauthorized access to certain pages in your Svelte application.


Setting Up the Project

To set up a new Svelte project, you can use the following command:

npx degit sveltejs/template svelte-protected-routes

Or you can download and extract the zip file from svelte.dev:

To quickstart, you can use the command above, or download the zip file

As noted at the beginning, we are going to make use of svelte-routing. To install it, run npm i svelte-routing. You can also remove everything from the src folder as we are going to start everything from scratch. Only leave an empty App.svelte, and your main.js.

Copied to clipboard! Playground
import App from './App.svelte';

const app = new App({
    target: document.body
});

export default app;
main.js

Adding Routes to Your App

If you start up your web server by running npm run dev, you should see an empty document. To add new routes to your Svelte app, add the following to your App.svelte:

Copied to clipboard!
<script>
    import { Router, Route } from 'svelte-routing';
    import ProtectedRoute from './ProtectedRoute.svelte';

    import Home from './routes/Home.svelte';
    import Dashboard from './routes/Dashboard.svelte';
</script>

<Router>
    <Route path="/" component={Home} />
    <ProtectedRoute path="/dashboard" component={Dashboard} />
</Router>
App.svelte

First, import two components from svelte-routing:

  • Router: This component is used for providing extra routing information to every Link and Route components inside it. Because of this, you need at least one top-level Router in your application.
  • Route: This component specifies a route. It expects a path property that defines when your component β€” that is passed to component β€” should be rendered.

I’ve also imported a custom ProtectedRoute component that we will use to protect pages from unauthorized access. At the moment, it does nothing, except renders a similar Route component, using the passed params:

Copied to clipboard!
<script>
    import { Route } from 'svelte-routing';

    export let path;
    export let component;
</script>

<Route path={path} component={component} />
ProtectedRoute.svelte

Lastly, for the sake of this tutorial, I’ve added two new dummy components inside a routes folder, one for a home page and one for the dashboard, both containing a single text:

Copied to clipboard!
<!-- for Home.svelte -->
<h1>πŸ‘‹ Welcome to the home page</h1>

<!-- for Dashboard.svelte -->
<h1>πŸ‘‹ Welcome to the dashboard</h1>
Home.svelte / Dashboard.svelte

If you try to go to /dashboard in your browser, you may get served a 404 page as it is trying to load a resource that is non-existent. To fix this and tell the server to always server the index.html no matter the route, change your package.json start script to the following:

Copied to clipboard!
"scripts": {
    "start": "sirv public --single"
}
package.json
Add the --single flag to your start script to fix routing
Looking to improve your skills? Learn how to build reactive apps with Svelte + Tailwind.
Master Svelteinfo Remove ads

Putting Protected Routes in Place

To implement protected routes, you want to put some form of authentication in place. It can be done in various ways, but for the sake of simplicity, we’re going to authenticate users based on the presence of a localStorage item, called token.

The following authentication method is unsafe and should not be used in a production environment. You should always verify users both on the client and server-side with robust, elaborate protection.

For this to work, we need to be able to reach the value globally throughout the app. It should be present in the global state. Luckily, in Svelte, this can be done pretty easily with the help of stores.

A store is a special type of object that has a subscribe method. It allows interested components to listen to the store and react to changes when it is updated. To create a new store, add a stores.js file to the root of your src folder with the following:

Copied to clipboard!
import { writable } from 'svelte/store';

export const token = writable(localStorage.getItem('token'));
stores.js

This will export a writeable store with the value of the token item in localStorage. To use this value for authentication, update your ProtectedRoute component with the following:

Copied to clipboard!
<script>
    import { Route, Link } from 'svelte-routing';
    import accessDenied from './routes/accessDenied.svelte';
    import { token } from './stores.js';

    export let path;
    export let component;

    $: isAuthenticated = $token;
</script>

{#if isAuthenticated}
    <Route path={path} component={component} />
{:else}
    <Route path={path} component={accessDenied} />
{/if}
ProtectedRoute.svelte

Here we can import the token we exported from stores.js, and use it as a reactive variable. If the user is authenticated, we’re good to render the requested page, otherwise, we can throw a 403. The 403 page, in this case, can render a link back to a safe place; the home page:

Copied to clipboard!
<script>
    import { Link } from 'svelte-routing';
</script>

<h1>No access πŸ€•</h1>
<h2>
    Go back to <Link to="/">Home page</Link>
</h2>
accessDenied.svelte

Updating the store

To update the store, let’s see how we can mock-login users through Home.svelte. Import Link and navigate from svelte-routing and implement the following function:

Copied to clipboard!
<script>
    import { Link, navigate } from 'svelte-routing';
    import { token } from '../stores.js';

    const login = () => {
        localStorage.setItem('token', '1');
        token.set(localStorage.getItem('token'));

        navigate('/dashboard', { replace: true });
    };
</script>

<h1>πŸ‘‹ Welcome to the home page</h1>
<h2>
    <Link to="dashboard">Go to Dashboard</Link>
</h2>
<span>or</span>
<h2>
    <span on:click={login}>Login</span>
</h2>
Home.svelte

Through this component, users can either go directly to the dashboard β€” without login, getting a 403 page β€” or click on the Login link, which executes the login function defined from line:5. It sets the localStorage, as well as updates the token. You can update the token β€” which is a writable store β€” through the set method. Once it is updated, the privateRoute component will gets notified.

Note that you can also trigger navigations programmatically if needed in svelte-routing with the navigate function. A common use-case is for triggering a redirection after a form submission.

Logging in for the protected route in Svelte

Logging the user out

Now there’s only one thing left to do; log the user out once they are logged in. We can use a similar behavior, only this time, let’s use a simple Link for navigation:

Copied to clipboard!
<script>
    import { Link } from 'svelte-routing';
    import { token } from '../stores.js';

    const logout = () => {
        localStorage.clear();
        token.set(localStorage.getItem('token'));
    }
</script>

<h1>πŸ‘‹ Welcome {'{'}user{'}'}</h1>
<h2>
    <Link to="/" on:click={logout}>Logout</Link>
</h2>
Dashboard.svelte
Note you need to use {'{'} to escape curly braces in Svelte components

The logout function will simply clears the localStorage and resets the value for the token, notifying PrivateRoute about the change once again.

Logging the user out in Svelte

Summary

svelte-routing makes routing pretty convenient in Svelte. And with some additional logic, you can easily implement some form of authentication for your users. Please note once again, you should not rely on the exact authentication method for production environments, as basically anyone could log in by simply tinkering with localStorage through DevTools.

If you would like to play around with the project in one piece, you can get it from the GitHub repository below. Do you have any thoughts about the tutorial? Let us know in the comments below! Thank you for reading through, happy coding!

Clone the project from GitHub

How to Make Your Very First Desktop App With Electron and Svelte
  • twitter
  • facebook
Did you find this page helpful?
πŸ“š More Webtips
Mentoring

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:

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.