Build your own SvelteKit Boilerplate: Auth0 Integration

Build your own SvelteKit Boilerplate: Auth0 Integration

ยท

5 min read

You know there's a German word for nearly everything. I've got a few German friends and I should ask them if there's a word to describe the feeling of mildest frustration and anticipation you experience when starting a new project.

After about three projects under your belt, you want to have a decent starting point for new projects so you can get into the meat of the problem quickly before your inspiration dries up.

I still find myself rebuilding the same pieces again and again. You can't create a boilerplate for every situation. Plus the web evolves, so I guess we're stuck in this perpetual state of developing.

6f6.jpg

via Imgur

Enter SvelteKit + Auth0

SvelteKit is my new latest and greatest go-to for new projects. I don't really want this post to be a fanboy praise session, so just trust me, it's good.

Auth0 is my go-to for authentication on new projects. They offer an amazing developer experience that scales from personal projects up to enterprise applications.

Let's build a boilerplate for new projects in SvelteKit with Auth0.

Whirlwind install process

I'm just going to put the code in here.

npm init svelte@next svelte-backpack
...(go through the prompts)
cd svelte-backpack
npm install
git init && git add -A && git commit -m "Initial commit"
npm run dev -- --open

The Prompts

Screenshot from 2021-08-11 08-23-19.png

In the interest of brevity, I'm not going to explain any of that. If you have any questions, reach out to me at @elliscs or Chris Ellis

gh repo create
...(go through the prompts)
git branch -M main
git push -u origin main

The Prompts ๐Ÿ˜€

Screenshot from 2021-08-11 08-42-45.png

I do have a little to say about that. The Github CLI is amazing to work with. It can definitely speed up your development if you work with a lot of projects. Great for repo maintainers as well.

Vorfreude

I checked with my friend and he described that feeling of anticipation when you're starting a new project as vorfreude.

It's what you experience on Christmas Eve before you get the presents.

That's it, exactly. For me, the excitement and anticipation of a new project coming to life.

via GIPHY: I couldn't use the same anyway meme

Make it work

First, we need to add the Auth0 SDK for Single Page Applications. Run the following, and restart your server.

npm install @auth0/auth0-spa-js

Brilliant. Now, head over to Auth0 and create your project.

  1. Login or create an account
  2. Click Create Application or navigate to your Applications
  3. Create your application and make note of your Domain & Client ID
  4. Set your Allowed Callback URLs, Allowed Logout URLs, & Allowed Web Origins to localhost:3000

Peek 2021-08-11 10-38.gif

Run the following

mkdir src/lib src/lib/config src/lib/services src/lib/stores
touch src/lib/config/auth_config.js src/lib/services/auth.js src/lib/stores/auth.js

Let's get our config setup.

// src/lib/config/auth_config.js
const config = {
    domain: 'dev-n08ck5ms.us.auth0.com',
    clientId: '4TZr5sk5mmpMi6OHOauHIoH0eafQjTnw'
};
export default config;

Next, we'll set up our Svelte stores.

// src/lib/stores/auth.js
import { writable } from 'svelte/store';

export const isAuthenticated = writable(false);
export const user = writable({});
export const popupOpen = writable(false);
export const error = writable();

Finally, we'll create our Auth Service.

// src/lib/services/auth.js
import createAuth0Client from '@auth0/auth0-spa-js';
import { user, isAuthenticated, popupOpen } from '$lib/stores/auth';
import config from '$lib/config/auth_config';

async function createClient() {
    let auth0Client = await createAuth0Client({
        domain: config.domain,
        client_id: config.clientId
    });

    return auth0Client;
}

async function loginWithPopup(client, options) {
    popupOpen.set(true);
    try {
        await client.loginWithPopup(options);

        user.set(await client.getUser());
        isAuthenticated.set(true);
    } catch (e) {
        // eslint-disable-next-line
        console.error(e);
    } finally {
        popupOpen.set(false);
    }
}

function logout(client) {
    return client.logout();
}

const auth = {
    createClient,
    loginWithPopup,
    logout
};

export default auth;

Recap

We just set up our client to handle login using Auth0 . We've got a config file for you to enter your own application details and a Svelte store for handling the client-side state.

We've also set up an Auth Service. This encapsulates many of the initial methods we need to run from Auth0 in a tidy package off in our lib folder.

It's time to use everything we've set up. ๐Ÿคž

Come-on, just log me in

Ok, fine.

// src/routes/index.svelte

<script>
    import { onMount } from 'svelte';
    import auth from '$lib/services/auth';
    import { isAuthenticated, user } from '$lib/stores/auth';

    let auth0Client;

    onMount(async () => {
        auth0Client = await auth.createClient();
        isAuthenticated.set(await auth0Client.isAuthenticated());
        user.set(await auth0Client.getUser());
    });

    function login() {
        auth.loginWithPopup(auth0Client);
    }

    function logout() {
        auth.logout(auth0Client);
    }
</script>
...

We import our service and store, and when the page mounts we create the Auth0 Client and update our store with the Auth0 details. We also need to log in and log out.

Annnndd...last but not least.

// src/routes/index.svelte
...
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>

{#if $isAuthenticated}
    <h2>Hey {$user.name}!</h2>
    {#if $user.picture}
        <img src={$user.picture} alt={user.name} />
    {:else}
        <img src="https://source.unsplash.com/random/400x300" alt="Random Photo" />
    {/if}
    <button on:click={logout}>Logout</button>
{:else}
    <button on:click={login}>Login</button>
{/if}

Svelte is incredibly readable so that should be pretty straightforward. We listen to the isAuthenticated and user stores. When they're populated we greet the user, show their picture, and offer Logout. Otherwise, we offer Login.

Let's test it out. Wish me luck!

Peek 2021-08-11 11-11.gif

TADA

That's it. We've added Auth0 Authentication to a SvelteKit application. It wasn't all that hard and frankly didn't take that long.

If you've never done it, I recommend you try rolling your own authentication just so you have an idea why you'd be happy to pay for a service like Auth0. It is such good value.

We are well on our way to making a reusable boilerplate for Svelte Kit applications. There are many more things that could go into this though.

I would expect your needs might differ from mine. Please let me know what you'd like to see next in this boilerplate at @elliscs or here Chris Ellis.

The repo is available at github.com/csellis/svelte-backpack. Feel free to fork, comment, star, etc. Heads up, this is not its final form.

Also, send me a DM if anything was confusing or needs to be reworked.

ย