---
url: 'https://www.corbado.com/blog/vuejs-passkeys'
title: 'Vue.js Passkeys: How to Implement Passkeys in Vue.js Apps'
description: 'Vue.js & Passkeys: Elevate your Vue.js projects with secure passkey implementation by following this developer tutorial.'
lang: 'en'
author: 'Vincent Delitz'
date: '2023-08-30T00:00:00.000Z'
lastModified: '2026-03-25T07:01:03.402Z'
keywords: 'Vue.js, Vue'
category: 'Passkeys Implementation'
---

# Vue.js Passkeys: How to Implement Passkeys in Vue.js Apps

## Key Facts

- **@corbado/web-js** adds passkey authentication to Vue.js 3 apps via a single npm
  install and a mountable UI component requiring no custom WebAuthn code.
- The **Relying Party ID** must be the bare domain only: no protocol, port or path. For
  local dev, use `localhost` not `http://localhost:5173`.
- **Corbado Complete** covers both passkey-first authentication and session management,
  enabling retrieval of user ID and name after login without extra backend work.
- The **VITE_CORBADO_PROJECT_ID** environment variable stores the Corbado project ID,
  connecting the Vue.js Vite frontend to the Corbado authentication backend.
- Using **Vue Router** with the `onLoggedIn` callback, the Corbado auth UI automatically
  redirects authenticated users to protected routes after passkey login.

## 1. Introduction

In this blog post, we'll be walking through the process of building a sample application
with passkey authentication using Vue.js. We'll cover how to embed the Corbado web-js UI
components and implement [passkey login](https://www.corbado.com/blog/passkey-login-best-practices) functionality
for a seamless user experience.

If you want to see the finished code, please have a look at our
[sample Vue.js passkey application repository on GitHub](https://github.com/corbado/example-passkeys-vuejs).

The result looks as follows:

![Vue.js Passkey Login Page](https://www.corbado.com/website-assets/Screenshot_2024_04_25_at_14_46_45_5e58c4c2fb.png)

## 2. Prerequisites

This tutorial assumes basic familiarity with Vue.js, HTML, CSS, and JavaScript. Let's dive
in! Moreover, you need to have Node and NPM installed on your machine.

We're using the Composition API and Vue 3 in this example.

## 3. Repository Structure

Let's first discuss the structure of our project
([full Vue.js passkeys GitHub repo](https://github.com/corbado/example-passkeys-vuejs)):

```
.
├── .env
├── package.json
├── vite.config.js
└── src
    ├── router
    |   └── login.component.ts
    ├── views
    |   ├── HomeView.vue
    |   └── ProfileView.vue
    ├── App.vue
    └── main.js
```

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

## 4. Set up the Vue.js Project

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

Let's start out by initializing a new Vue.js project. In this tutorial, were using Vue.js
version 3.3.4:

```bash
npm init vue@latest
```

In the installation guide steps, we select the following:

- Ok to proceed: Yes
- Project name: passkeys-demo-vuejs
- Add TypeScript: No
- Add JSX Support: No
- Add Vue Router for SPA: Yes
- Add Pinia for state management: No
- Add Vitest for unit testing: No
- Add an End-to-End Testing Solution?: No
- Add ESLint for code quality: No
- Add Vue DevTools 7 extension for debugging? (experimental): No

Then run

```bash
cd passkeys-demo-vuejs
```

Let's also install the [Corbado web-js](https://www.npmjs.com/package/@corbado/web-js)
dependency:

```bash
npm i @corbado/web-js
```

If you run

```bash
npm run dev
```

the sample skeleton application starts at [http://localhost:5173](http://localhost:5173):

![Vue.js Start Page](https://www.corbado.com/website-assets/64efb148dd59079f4bf2028c_vuejs_start_page_8bdd07dde9.png)

## 5. Set Up the Corbado UI Components for Passkey Authentication

### 5.1 Set Up Your Corbado Account and Project

Visit the
[Corbado developer panel](https://app.corbado.com/signin#register?framework=Vue.js&technology=passkeys)
to sign up and create your account (you'll see the passkey sign-up in action here!).

![Vue.js Corbado Developer Panel Sign-up](https://www.corbado.com/website-assets/dev_panel_d7f6cc96ed.png)

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 Vue.js as your framework. In the
application settings, define your Application URL and
[Relying Party](https://www.corbado.com/glossary/relying-party) ID as follows:

![App settings](https://www.corbado.com/website-assets/application_settings_e7049b45fa.png)

- **Application URL:** Provide the URL where you embedded the UI component, here:
  [http://localhost:5173](http://localhost:5173).
- [**Relying Party ID**](https://www.corbado.com/blog/webauthn-relying-party-id-rpid-passkeys)**:** Provide the
  domain (no protocol, no port and no path) where passkeys should be bound to, here:
  `localhost`

Lastly, retrieve your project ID from the developer panel and store it in your environment
file. You can find it [here](https://app.corbado.com/app/settings/general/project-info)
under Corbado API access.

Your environment file should look like this:

```dotenv
VITE_CORBADO_PROJECT_ID=<your-project-id>
```

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

### 5.2 Embed the UI Component in Your Frontend

Now, let's jump back to the code we created from [step 4](#set-up-the-vuejs-project).

Delete the entire `/src/components` folder to clean up the project and rename the
`/src/views/AboutView.vue` file to `/src/views/ProfileView.vue`, so it fits our logic
better.

Open the `/src/router/index.js` file and change the `/about` route to `/profile` (change
the name accordingly and don't forget to import the component):

```javascript
// src/router/index.js

import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView.vue";
import ProfileView from "@/views/ProfileView.vue";

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: [
        {
            path: "/",
            name: "home",
            component: HomeView,
        },
        {
            path: "/profile",
            name: "profile",
            component: ProfileView,
        },
    ],
});

export default router;
```

In the `App.vue` file, import the global Corbado object and use it to initialize the
Corbado project. We need to hand it our project ID from the `.env` file and set the dark
mode to "on". After the initialization, we set `isInitialized` to true to show our page:

```vue
<!-- src/App.vue -->

<script setup>
import { RouterView } from "vue-router";
import Corbado from "@corbado/web-js";
import { ref } from "vue";

const isInitialized = ref(false);

Corbado.load({
    projectId: import.meta.env.VITE_CORBADO_PROJECT_ID,
    darkMode: "on",
}).then(() => {
    isInitialized.value = true;
});
</script>

<template>
    <div v-if="isInitialized">
        <RouterView />
    </div>
</template>
```

Then, we use the global Corbado object to mount the authentication UI in the
`HomeView.vue` file. We'll make it redirect the user to the `/profile` page once he
authenticates or if he's already signed in.

```vue
<!-- src/views/HomeView.vue -->

<script setup>
import { onMounted, ref } from "vue";
import Corbado from "@corbado/web-js";
import { useRouter } from "vue-router";

const router = useRouter();
const authElement = ref(null);

onMounted(() => {
    if (Corbado.isAuthenticated) {
        router.push("/profile");
    }
    Corbado.mountAuthUI(authElement.value, {
        onLoggedIn: () => {
            router.push("/profile");
        },
        isDevMode: true,
    });
});
</script>

<template>
    <div ref="authElement"></div>
</template>
```

### 5.3 Set Up the Profile Page

After successful authentication, the Corbado auth component redirects the user to the
profile page. This page renders basic user information
([user ID](https://www.corbado.com/blog/webauthn-user-id-userhandle) and name) and provides a button to logout.
It makes use of the Corbado object to retrieve the user data and logs him out if needed.

Create a `ProfileView.vue` file and add the following code:

```html
<!-- src/views/ProfileView.vue -->
<script setup>
    import { useRouter } from "vue-router";
    import Corbado from "@corbado/web-js";
    import { ref, onMounted } from "vue";

    const user = ref(null);
    const router = useRouter();

    function redirectToHome() {
        router.push("/");
    }

    async function handleLogout() {
        user.value = null;
        await Corbado.logout();
        redirectToHome();
    }

    onMounted(() => {
        user.value = Corbado.user;
    });
</script>

<template>
    <div>
        <div v-if="user">
            <h1>Profile Page</h1>
            <p>
                User-ID: {{ user.sub }}
                <br />
                Name: {{ user.name }}
            </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 <a @click="redirectToHome">home</a> to log in.</p>
        </div>
    </div>
</template>
```

If the user isn't logged in, we also provide him with the option to go back to the home
page and log in.

### 5.4 Start Using Passkeys

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

```bash
npm run dev
```

You should see the following screen:

![Vue.js Passkey Login Page](https://www.corbado.com/website-assets/Screenshot_2024_04_25_at_14_46_45_5e58c4c2fb.png)

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

![Vue.js Passkey Profile Page](https://www.corbado.com/website-assets/Screenshot_2024_04_25_at_17_11_50_f46727a008.png)

## 6. Conclusion

This tutorial showed how easy it is to add
[passwordless authentication](https://www.corbado.com/glossary/passwordless-authentication) with passkeys to a
Vue.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 you can leverage Corbado's session management to retrieve backend
data, please check our documentation [here](https://docs.corbado.com/sessions/overview)or
if you want to add Corbado to your existing app with existing users, please see our
documentation [here](https://docs.corbado.com/products/corbado-connect).

## Frequently Asked Questions

### Do I need to write WebAuthn code manually to implement passkeys in a Vue.js app?

No manual WebAuthn code is required. The @corbado/web-js package provides a pre-built UI
component that you mount onto a DOM element using `Corbado.mountAuthUI()`, handling all
WebAuthn interactions internally. You only need to configure your project ID and define
redirect behavior after login.

### What is the difference between Application URL and Relying Party ID when setting up passkeys in Vue.js with Corbado?

The Application URL is the full address where your UI component is hosted, such as
`http://localhost:5173`. The Relying Party ID is strictly the domain without protocol,
port or path, such as `localhost`, and determines which domain passkeys are
cryptographically bound to.

### How do I protect a Vue.js route so only authenticated passkey users can access it?

In your view component's `onMounted` hook, check `Corbado.isAuthenticated` and redirect
unauthenticated users back to the login page using Vue Router's `router.push()`. The
`onLoggedIn` callback passed to `Corbado.mountAuthUI()` handles the forward redirect after
a successful passkey authentication.

### How do I retrieve user data and handle logout after passkey login in a Vue.js app using Corbado?

After authentication, access the logged-in user's details via `Corbado.user`, which
exposes fields like `sub` (user ID) and `name`. To log out, call `await Corbado.logout()`
and then redirect the user back to the home page using Vue Router.
