remix-passkeysPasskeys Implementation

How to Build a Remix 2 Passkey Login

This tutorial shows how to implement passkeys in Remix apps. Using the Corbado Remix component adding passkeys is a matter of a few lines of code.

Blog-Post-Author

Lukas

Created: March 18, 2024

Updated: September 3, 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

In this blog post, well be walking through the process of building a sample application with passkey authentication using Remix 2. Well cover how to embed the Corbado Remix component and implement passkey login functionality for a seamless user experience.

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

The result looks as follows:

Remix Passkeys Signup Page

2. Prerequisites

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

3. Repository structure

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

. ├── .env ├── package.json └── app ├── entry.client.tsx ├── root.tsx ├── utilities │ ├── AuthComponent.client.tsx │ └── ProfileComponent.client.tsx └── routes ├── _index.tsx └── profile.tsx

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

Slack Icon

Become part of our Passkeys Community for updates and support.

Join

4. Set up the Remix Project

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

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

npx create-remix@latest --template remix-run/remix/templates/vite

You will be prompted the following options:

Where should we create your new project?

  • If you already have a project folder, just choose "." otherwhise choose any name you like

Initialize a new git Repository?

  • We recommend to opt for "yes" here

Install dependencies with npm?

  • Choose yes

If you created a new project directory, navigate into it with:

cd <your directory name>

If you run

npm run dev

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

Remix Sample Application

5. Set up the Corbado Remix 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!).

Corbado Developer Panel

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, youll get more foundational setup guidance. The subsequent sections of this article will delve into the integration part.

Next, we set the Application URL and Relying Party ID inside Settings > General > URLs to the following values (see explanation below):

Corbado Developer Panel URL Settings

  • Application URL: Provide the URL where your application is running, 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

5.2 Embed the Remix component in your Frontend

First, we need to install the React component with its corresponding types, so that we have full typescript support:

npm i @corbado/react @corbado/types

First, delete the server entry file under /app/entry.server.tsx as we wont need any custom logic for the server entrypoint here. If this file isnt present, Remix will automatically handle the logic for us.

Create a .env file and put your Corbado Project Id found under Settings > General > Project info inside.

VITE_PUBLIC_CORBADO_PROJECT_ID=<Your project ID>

Now, head into the entry.client.tsx file and wrap your entire application with the CorbadoProvider. Hand it your project id from the environment and set darkMode to off. Theres much more configuration possible which you can find in our docs.

import { RemixBrowser } from "@remix-run/react"; import { startTransition, StrictMode } from "react"; import { hydrateRoot } from "react-dom/client"; import { CorbadoProvider } from "@corbado/react"; startTransition(() => { hydrateRoot( document, <StrictMode> <CorbadoProvider projectId={import.meta.env.VITE_PUBLIC_CORBADO_PROJECT_ID} darkMode="off"> <RemixBrowser /> </CorbadoProvider> </StrictMode> ); });

For all of the components and hooks were going to use from Corbado well need a workaround in order to prevent the Corbado React Package from being inlcuded inside the server bundle during build. This can be achieved by only using the Corbado React package inside files that have .client before their file extension (e.g. someComponent.client.tsx) and providing a fallback for the components during ssr. This can be achieved by exporting a clientLoader as well as a HydrateFallback from your Components (find documentation on this here). Youll see this in action in the coming steps.

Next, well need some utilities which we are going to place inside /app/utilities. Start by creating an AuthComponent.client.tsx file. The useCorbado hook provides us with authentication related information and the CorbadoAuth component manages all signup and login flows including fallback solutions for us.

import { CorbadoAuth, useCorbado } from "@corbado/react"; import { useNavigate } from "@remix-run/react"; export default function AuthComponent() { const { isAuthenticated, loading } = useCorbado(); const navigate = useNavigate(); if (isAuthenticated && !loading) { navigate("/profile"); } function onLoggedIn() { navigate("/profile"); } return <CorbadoAuth onLoggedIn={onLoggedIn} />; }

If the user is already authenticated or once he authenticates, well redirect him to the /profile route.

Remove the skeleton code from _index.tsx and display our component inside of the Index function. For the mentioned workaround we now have to export two more functions:

The hydrateFallback which will tell Remix what fallback we want to use during server side rendering as well as a clientLoader to enforce rendering on the client. You can read more about this here.

import type { MetaFunction } from "@remix-run/node"; import AuthComponent from "~/utilities/AuthComponent.client"; export const meta: MetaFunction = () => { return [ { title: "New Remix App" }, { name: "description", content: "Welcome to Remix!" }, ]; }; // this is needed so ssr of the AuthComponent is prevented export function clientLoader() { return null; } // Provide a fallback for ssr as trying to render Corbado Components on the server doesn't work export function HydrateFallback() { return <p>Loading...</p>; } export default function Index() { return ( <div> <AuthComponent /> </div> ); }

5.3 Set up the Profile Page

Now, lets create the Profile page. Create another utility called ProfileComponent.client.tsx. Here, well use useCorbado once again to retrieve authentication state and a logout utility as well as the useCorbadoSession hook to retrieve the user object, which lets us access information like his name and email. If the user isnt authenticated, well redirect him to the homepage where our auth component is displayed. We also incldue the PasskeyList component which lets the user view and manage his existing passkeys.

import { PasskeyList, useCorbado, useCorbadoSession } from "@corbado/react"; import { useNavigate } from "@remix-run/react"; export default function Profile() { const navigate = useNavigate(); const { logout, isAuthenticated, loading } = useCorbado(); const { user } = useCorbadoSession(); if (!isAuthenticated && !loading) { navigate("/"); } return ( <div style={{maxWidth: "600px", margin:"0 auto"}}> <h1>Profile</h1> <p>Name: {user?.name}</p> <p>Email: {user?.email}</p> <button onClick={logout}>Logout</button> <PasskeyList /> </div> ); }

Lastly, create the profile route by creating a profile.tsx file under /app/routes and apply the same workaround as in _index.tsx.

import ProfileComponent from "~/utilities/ProfileComponent.client"; export function clientLoader() { return null; } export function HydrateFallback() { return <p>Loading...</p>; } export default function Profile() { return <ProfileComponent />; }

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:

Corbado Passkeys Signup Screen

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

Corbado Remix Profile Page

Remix Icon

Add passkeys to your Remix app.

Start For Free

6. Conclusion

This tutorial showed how easy it is to add passwordless authentication with passkeys to a Remix 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 Corbados 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