Passkeys in Nuxt.js: Step-by-step guide for developers to integrate passkeys in Nuxt.js applications for improved security.
Lukas
Created: September 6, 2023
Updated: February 17, 2025
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.
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
In this blog post, well be walking through the process of building a sample application with passkey authentication using Nuxt.js. Well cover the setup of the Corbado UI component as well as the implementation of 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:
This tutorial assumes basic familiarity with Nuxt.js, HTML, CSS and JavaScript. Lets dive in! Moreover, you need to have Node and NPM installed on your machine.
Lets first discuss the structure of our project:
. ├── .env ├── package.json ├── nuxt.config.ts ├── pages | ├── index.vue | └── profile.vue ├── layouts | └── default.vue .
The rest of the files of this project can be ignored for the purpose of this tutorial.
In the following, we explain step-by-step what needs to be done to successfully set up the Nuxt.js project.
Lets start out by initializing a new Nuxt.js project:
npx nuxi@latest init passkeys-demo-nuxtjs
Select npm as package manager and press enter. After initialization, execute the following commands to set up your project:
cd passkeys-demo-nuxtjs npm install
If you now run
npm run dev
the sample skeleton application starts at http://localhost:3000.
Visit the Corbado developer panel to sign up and create your account (you'll see the passkey sign-up in action here!).
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.
Next, choose "Web app" as an application type and Nuxt as your framework. In the application settings, define your application url and relying party id as follows:
Lastly, retrieve your project ID from the developer panel and store it in your environment file. You can find it here under Corbado API access.
Your environment file should look like this:
VITE_CORBADO_PROJECT_ID=<your-project-id>
You'll need it later to embed the Corbado UI component in your Nuxt app.
Install the Corbado web-js library with
npm i @corbado/web-js
Optionally, you can also install the Corbado types to enhance your typescript experience:
npm i -D @corbado/types
First, let's set up our layout under /layouts/default.vue
which handles initialization of our Corbado project.
<script setup lang="ts"> import Corbado from "@corbado/web-js" import {onMounted} from "vue"; const isInitialized = useState('isInitialized', () => false) const projectId = import.meta.env.VITE_CORBADO_PROJECT_ID onMounted(async () => { await Corbado.load({ projectId: projectId, darkMode: "off" }) isInitialized.value = true }) </script> <template> <div v-if="isInitialized"> <slot/> </div> </template>
We'll only render any descendants once our Corbado project has initialized which is ensured by our isInitialized
state
together with the conditional rendering of the <slot/>
component.
Most of your Corbado project is configured in this Corbado.load
call.
An extensive list of options can be
found here.
Let's now set up our login / auth page under pages/index.vue
.
We'll create a reference to a div inside our template with the authElement
state and then use it in our onMounted to
mount the Corbado auth UI.
We have to specify an onLoggedIn
callback that's executed on either signin or signup and redirects to the profile page
in our case.
<script setup lang="ts"> import Corbado from "@corbado/web-js" import {onMounted} from "vue"; const authElement = useState<HTMLDivElement | undefined>('authElement', () => undefined) onMounted(() => { if (authElement.value) { Corbado.mountAuthUI(authElement.value, { onLoggedIn: () => { navigateTo("/profile") }, }) } }) </script> <template> <div ref="authElement"></div> </template>
After successful authentication, the Corbado auth UI redirects the user
to the provided Redirect URL (/profile
). This page
renders basic user information (user ID and email) and provides a button to
logout. Create the file pages/profile.vue
and add the following code:
<script setup lang="ts"> import Corbado from "@corbado/web-js" const user = Corbado.user async function handleLogout() { await Corbado.logout() await navigateTo("/") } </script> <template> <div> <div v-if="user"> <h1>Profile Page</h1> <p> User-ID: {{ user.sub }} <br /> Email: {{ user.email }} </p> <button @click="handleLogout">Logout</button> </div> <!-- Show the "not logged in" message if the user is not logged in --> <div v-else> <p>You're not logged in.</p> <p> Please go back to <NuxtLink href="/">home</NuxtLink> to log in. </p> </div> </div> </template>
This page has content that should only be visible to authenticated users. Therefore, we use Corbado session management in the code above. If the user isn't authenticated, we provide him with a link to the home page.
If everything is set up and installed, run the application with
npm run dev
You should see the following screen:
After successful sign up / login, you should see the profile page:
This tutorial showed how easy it is to add passwordless authentication with passkeys to a Nuxt.js 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 Corbado's session management please check the docs here.
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.