sveltekit-passkeysPasskeys Implementation

How to Build SvelteKit Apps with Passkeys

A developer tutorial on how to implement passkeys in SvelteKit apps. We show how to integrate passkeys using UI components, Flowbite (Tailwind CSS) and npm.

Blog-Post-Author

Lukas

Created: January 29, 2024

Updated: September 20, 2024


We aim to make the Internet a safer place using passkeys. That's why we want to support developers with tutorials on how to implement passkeys.

1. Introduction

2. Prerequisites

3. Svelte Passkey Repository Structure

4. Set Up the Svelte project

5. Set Up the Corbado UI Component for Passkey Authentication

    5.1 Set Up your Corbado Account and Project

    5.2 Embed the UI Component in your Frontend

    5.3 Set Up the Profile Page

    5.4 Start Using Passkeys

6. Conclusion

1. Introduction

In this blog post, we'll be walking through the process of building a sample application with passkey authentication using Sveltekit. We'll cover how to embed the Corbado UI component and implement passkey login functionality for a seamless user experience. Furthermore, we'll use the Corbado node sdk to retrieve user information on the server.

If you want to see the finished code, please have a look at our sample application GitHub repository:

The result looks as follows:

Sveltekit Passkeys Login Page

2. Prerequisites

This tutorial assumes basic familiarity with Svelte, HTML, CSS and JavaScript. Lets dive in! Moreover, you need to have Node and NPM installed on your machine.

3. Svelte Passkey Repository Structure

Lets first discuss the structure of our project (full GitHub repo):

. ├── .env ├── package.json └── src ├── app.html └── routes ├── +layout.svelte ├── +layout.server.ts ├── +page.svelte └── profile ├── +page.server.ts └── +page.svelte

The rest of the files of this project can be ignored for the purpose of this tutorial.

4. Set Up the Svelte Project

In the following, we explain step-by-step what needs to be done to successfully set up the Svelte project.

Lets start out by initializing a new Svelte project. In this tutorial, were using Svelte version 4.2.7:

npm create svelte@latest example-passkeys-svelte

In the installation guide steps, we select the following (if youre asked to install or update the create-svelte package, click Yes to proceed):

  • App template: Skeleton project
  • Type checking with TypeScript: We're using TypeScript here, but feel free to choose whatever you prefer.
  • Additional options: We're using ESLint and Prettier

If you're asked to proceed click "Yes"

cd example-passkeys-svelte

Let's also install the Corbado web-js and node-sdk dependencies:

npm i @corbado/web-js @corbado/node-sdk

Optionally, you can also install the Corbado types for an enhanced typescript experience:

npm i -D @corbado/types

If you run

npm install

and

npm run dev

the sample Svelte skeleton application starts at http://localhost:5173:

Svelte Passkeys Skeleton

5. Set Up the Corbado UI Component for Passkey Authentication

5.1 Set up your Corbado account and project

Visit the Corbado developer panel to sign up and create your account (you'll see the passkey sign-up in action here!).

Sveltekit Corbado Developer Panel Sign-up

In the project setup wizard, begin by selecting an appropriate name for your project. For the product selection, opt for "Corbado Complete". Subsequently, specify your technology stack and select "DEV along with "Corbado session management" options. Afterwards, you'll get more foundational setup guidance.

Next, choose "Web app" as an application type and Svelte as your framework. In the application settings, define your application url and relying party id as follows:

App settings

  • Application URL: Provide the URL where you embedded the UI component, here: http://localhost:5173.
  • Relying Party ID: Provide the domain (no protocol, no port and no path) where passkeys should be bound to, here: localhost

Then, retrieve your project ID, API secret, Frontend API and Backend API URLs from the developer panel and store it in your environment file. You can find it here under Corbado API access.

Screenshot 2024-09-16 at 18.01.13.png

Your environment file should look like this:

PUBLIC_CORBADO_PROJECT_ID=<your-corbado-project-id> CORBADO_API_SECRET=<your-corbado-api-secret> CORBADO_FRONTEND_API=<you-corbado-frontend-api-url> CORBADO_BACKEND_API=<your-corbado-backend-api-url>

You'll need it later to embed the Corbado UI component in your Svelte app.

5.2 Embed the UI Component in the Frontend

Now, lets jump back to the code we created from step 4.

First, we'll disable ssr as that's currently not supported by the Corbado web-js package, but we're working on it ;)

We'll do that by creating a +layout.server.ts file with the following content:

export const ssr = false;

Then, we'll create our outer layout which will handle the initialization of our Corbado project. It acts as a boundary that only renders the rest of the app once the Corbado project is initialized.

<script lang="ts"> import Corbado from "@corbado/web-js"; import {onMount} from "svelte"; import { PUBLIC_CORBADO_PROJECT_ID } from '$env/static/public'; let isInitialized = false; onMount(async () => { await Corbado.load({ projectId: PUBLIC_CORBADO_PROJECT_ID, darkMode: 'off', setShortSessionCookie: true }); isInitialized = true; // Set to true once Corbado is initialized }); </script> <div> {#if isInitialized} <slot></slot> {/if} </div>

It's important that we provide the setShortSessionCookie: true config option, so a cookie is created on login, which we'll need later to retrieve user data on the server.

Next, we modify the home page. The home page is the file in src/routes/+page.svelte. This file contains the sign up / login UI component and navigates to /profile once the user is authenticated.

<script lang="ts"> import Corbado from '@corbado/web-js'; import {onMount} from 'svelte'; let authElement: HTMLDivElement; onMount(() => { Corbado.mountAuthUI( authElement, { onLoggedIn: () => window.location.href = "/profile", }) }) </script> <div bind:this={authElement}></div>

5.3 Set Up the Profile Page

Lastly, let's create the profile page under the /profile route. To demonstrate our node SDK's capabilitys, we'll retrieve all user information on the server, so let's create our +page.server.ts file.

First, let's import everything we need, including our environement variables and set up the Corbado node SDK:

import { type RequestEvent } from '@sveltejs/kit'; import { PUBLIC_CORBADO_PROJECT_ID } from '$env/static/public'; import { CORBADO_API_SECRET, CORBADO_FRONTEND_API, CORBADO_BACKEND_API } from '$env/static/private'; import { SDK, Config } from '@corbado/node-sdk'; const config = new Config(PUBLIC_CORBADO_PROJECT_ID, CORBADO_API_SECRET, CORBADO_FRONTEND_API, CORBADO_BACKEND_API); const sdk = new SDK(config);

Next, we'll create a load function that retrieves the request cookies and from it the cbo_short_session cookie which stores our jwt session. We'll handle all cases and either return a user object with his email and id or an undefined user, so we can determine during render whether the user is logged in.

export async function load({ request }: RequestEvent) { const cookies = parseCookies(request.headers.get('Cookie') || ''); const cbo_short_session: string | undefined = cookies.cbo_short_session; if (!cbo_short_session) { return { id: undefined } } try { const user = await sdk.sessions().validateToken(cbo_short_session); return { id: user.userId }; } catch { return { id: undefined } } } function parseCookies(cookieHeader: string): Record<string, string> { return Object.fromEntries( cookieHeader.split(';').map((cookie) => { const [name, ...rest] = cookie.trim().split('='); return [name, rest.join('=')]; }) ); }

The corresponding page will access our loader's data and show the user's name and user ID and provides a button to log out. If the user isn't logged in, we'll display a link back to the homepage.

<script lang="ts"> import type { PageData } from './$types'; import Corbado from '@corbado/web-js'; import { goto } from '$app/navigation'; export let data: PageData async function handleLogout() { await Corbado.logout() await goto("/") } </script> <div> {#if (data.id)} <h1> Profile Page </h1> <p> User-id: {data.id} </p> <button on:click={handleLogout}> Logout </button> {:else} <h1> You aren't logged in. </h1> <p>Go <a href="/">Home</a></p> {/if} </div>

With the combination of the web-js package and the node-sdk we have access to authentication information on the client and the server. If you're interested in what the profile page would look like if we had retrieved user information on the client side, take a look at our Svelte blog post.

5.4 Start Using Passkeys

If everything is set up and installed, run the application with

npm run dev

You should see the following screen:

Svelte Passkeys Login Page

After successful sign up / login, you see the profile page:

Svelte Passkeys Profile Page

6. Conclusion

This tutorial showed how easy it is to add passwordless authentication with passkeys to a Svelte app using Corbado. Besides the passkey-first authentication, Corbado provides simple session management, that we used for a retrieval of basic user data. If you want to read more about how you can leverage Corbado's session management to retrieve backend data, please check out our documentation here or if you want to add Corbado to your existing app with existing users, please see our documentation here.

Share this article


LinkedInTwitterFacebook

Table of Contents

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.


We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour

Start for free