Vue 3 Facebook Login with OAuth2: Full Tutorial & Example

by Didin J. on May 28, 2025 Vue 3 Facebook Login with OAuth2: Full Tutorial & Example

Learn how to add Facebook Login to your Vue 3 app using the Composition API, Vue Router, and Facebook SDK with route protection and UX enhancements

In this Vue 3 tutorial, you'll learn how to build a Facebook Login authentication system using the Composition API and Vue Router. We'll start by creating and configuring a Facebook Developer App to enable secure Facebook OAuth integration. On the frontend, we'll implement the login functionality using the official Facebook JavaScript SDK for seamless social login in your Vue application.


Part 1. Set up a Facebook Developer App

To use Facebook Login in your Vue 3 application, you'll need a Facebook App ID. Follow these steps to create one:

✅ Step 1: Go to the Facebook Developer Portal

Visit https://developers.facebook.com and log in with your Facebook account.

✅ Step 2: Create a New App

1. Click "My Apps" > "Create App"

2. Select "Consumer" as the app type and click "Next"

3. Enter:

   * App Name (e.g., Vue3SocialLoginApp)

   * Your email address

4. Click "Create App"

✅ Step 3: Choose a Use Case

1. Choose "Authenticate and request data from users with Facebook Login"

2. Click the "Next" button

3. In "Which business portfolio would you like to connect to this app?", click I don't want to connect my business portfolio yet. Click the "Next" button.

4. Skip "Condition" by clicking the "Next" button.

5. In "General Description" click "Open Dashboard"

✅ Step 4: Configure the Login

1. Go to Application Settings -> Base

2. Copy the Application ID and secret for later use in the Vue application

3. Click "+ Add Platform" then choose Website

4. Fill in the "Site URL"

   http://localhost:5173

5. Click the "Save Changes" button

✅ Optional: Make the App Live

By default, the app is in development mode, which only works with Facebook users assigned as testers/developers.

1. Go to App Review > Permissions and Features

2. Toggle the app to Live

3. Add domains under Settings > Basic > App Domains if needed


Part 2: Create a New Vue 3 Project

npm init vue@latest

Choose options:

  • ✔ Project name: vue3-facebook-login
  • ✔ TypeScript: Optional (I'll use plain JS in this tutorial unless you prefer TS)
  • ✔ Vue Router: Yes
  • ✔ Pinia: Optional (we’ll use basic state handling unless you prefer Pinia)
  • ✔ ESLint/Prettier: Optional

Then:

cd vue3-facebook-login
npm install
npm run dev

Vue 3 Facebook Login Tutorial with Composition API and Router - vue home


Part 3: Project Structure

Your folder structure should look like:

src/
├── assets/
├── components/
│   └── FacebookLogin.vue
├── views/
│   ├── Home.vue
│   └── Profile.vue
├── router/
│   └── index.js
├── App.vue
└── main.js


Part 4: Add Facebook SDK

In index.html, before the closing </body> tag, add:

<!DOCTYPE html>
<html lang="">

<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vite App</title>
</head>

<body>
  <div id="app"></div>
  <script type="module" src="/src/main.js"></script>
  <script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js"></script>
</body>

</html>

 

Part 5: Set Up Vue Router

Create a src/router folder and add an index.js file:

import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import Profile from '../views/Profile.vue';

const routes = [
  { path: '/', name: 'Home', component: Home },
  { path: '/profile', name: 'Profile', component: Profile },
];

export default createRouter({
  history: createWebHistory(),
  routes,
});

In main.js, add the router:

import "./assets/main.css";

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";

createApp(App).use(router).mount("#app");


Part 6: Facebook Login Component

Create a file src/components/FacebookLogin.vue, then add:

<template>
  <div>
    <button @click="loginWithFacebook">Login with Facebook</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';

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

window.fbAsyncInit = function () {
  FB.init({
    appId: 'YOUR_FB_APP_ID',
    cookie: true,
    xfbml: true,
    version: 'v19.0',
  });
};

const loginWithFacebook = () => {
  FB.login((response) => {
    if (response.authResponse) {
      FB.api('/me', { fields: 'name,email,picture' }, function (profile) {
        user.value = profile;
        localStorage.setItem('fb_user', JSON.stringify(profile));
        router.push('/profile');
      });
    }
  }, { scope: 'public_profile,email' });
};
</script>


Part 7: Home and Profile Views

Create a folder views and a file src/views/Home.vue, then add:

<template>
    <div>
        <h1>Home Page</h1>
        <FacebookLogin />
    </div>
</template>

<script setup>
import FacebookLogin from '../components/FacebookLogin.vue';
</script>

Create a file src/views/Profile.vue, then add:

<template>
    <div v-if="user">
        <h1>Welcome, {{ user.name }}</h1>
        <img :src="user.picture.data.url" alt="profile" />
        <p>{{ user.email }}</p>
        <button @click="logout">Logout</button>
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';

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

onMounted(() => {
    const storedUser = localStorage.getItem('fb_user');
    if (storedUser) {
        user.value = JSON.parse(storedUser);
    } else {
        router.push('/');
    }
});

const logout = () => {
    FB.logout(() => {
        localStorage.removeItem('fb_user');
        router.push('/');
    });
};
</script>

We’ll use a global beforeEach guard to check if the user is authenticated (i.e., has Facebook login data stored in localStorage) before allowing access to protected routes.

1. Update Your Router (src/router/index.js)

We’ll define a meta field to mark routes that require authentication.

import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import Profile from '../views/Profile.vue';

const routes = [
  { path: '/', name: 'Home', component: Home },
  {
    path: '/profile',
    name: 'Profile',
    component: Profile,
    meta: { requiresAuth: true }, // ✅ protected route
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

// 🔒 Global navigation guard
router.beforeEach((to, from, next) => {
  const user = JSON.parse(localStorage.getItem('fb_user'));

  if (to.meta.requiresAuth && !user) {
    next('/'); // redirect to home if not authenticated
  } else {
    next(); // proceed
  }
});

export default router;

2. Test the Protection

Try visiting /profile manually in the browser:

  • ✅ If you're logged in (with fb_user in localStorage), it should load
  • ❌ If you're not logged in, it will redirect you back to /

Optional: Add a Logout Redirect

To improve UX, you might want to redirect the user to the home page after logging out. Update the logout() function in Profile.vue:

const logout = () => {
  FB.logout(() => {
    localStorage.removeItem('fb_user');
    router.push('/'); // redirect to home after logout
  });
};

You're now protecting private routes with Facebook login! ✅


Part 9: Optional Improvements

1. Show a Flash Message on Route Redirect

Improve the UX by letting users know why they got redirected (e.g., not logged in). You can do this with a basic global state or a third-party toast library.

👉 Basic Flash Message Example (using reactive global state)

Create a stores folder and a simple flash message store (src/stores/flash.js):

import { reactive } from 'vue';

export const flash = reactive({
  message: '',
  set(msg) {
    this.message = msg;
    setTimeout(() => (this.message = ''), 3000); // clear after 3s
  },
});

Use it in App.vue:

<template>
  <div id="app">
    <div v-if="flash.message" class="flash">{{ flash.message }}</div>
    <router-view />
  </div>
</template>

<script setup>
import { flash } from './stores/flash';
</script>

<style>
.flash {
  background: #ffeb3b;
  padding: 10px;
  text-align: center;
}
</style>

Update your router/index.js:

import { flash } from '../stores/flash';

router.beforeEach((to, from, next) => {
  const user = JSON.parse(localStorage.getItem('fb_user'));
  if (to.meta.requiresAuth && !user) {
    flash.set('You must be logged in to access that page.');
    next('/');
  } else {
    next();
  }
});

2. Automatically Load Facebook User Data on Refresh

If the user refreshes the page, you might want to reinitialize the Facebook SDK and ensure the user is still logged in:

FB.getLoginStatus(function(response) {
  if (response.status === 'connected') {
    FB.api('/me', { fields: 'name,email,picture' }, function(userInfo) {
      localStorage.setItem('fb_user', JSON.stringify(userInfo));
    });
  }
});

Call this inside App.vue on mount or when the app loads.

3. Add a Facebook Login Button Component

To reuse the login button, move it to components/FacebookLoginButton.vue:

<template>
  <button @click="loginWithFacebook">Login with Facebook</button>
</template>

<script setup>
import { useRouter } from 'vue-router';

const router = useRouter();

function loginWithFacebook() {
  FB.login((response) => {
    if (response.authResponse) {
      FB.api('/me', { fields: 'name,email,picture' }, (userInfo) => {
        localStorage.setItem('fb_user', JSON.stringify(userInfo));
        router.push('/profile');
      });
    }
  }, { scope: 'public_profile,email' });
}
</script>

4. Use a Toast Notification Library

Instead of the basic flash, you can use Vue Toastification or vue-notification.

Example using Toastification:

npm install vue-toastification --legacy-peer-deps

In main.js:

import "./assets/main.css";

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import Toast from "vue-toastification";
import "vue-toastification/dist/index.css";

createApp(App).use(router, Toast).mount("#app");

Then in components:

import { useToast } from 'vue-toastification';

const toast = useToast();

const loginWithFacebook = () => {
    FB.login((response) => {
        if (response.authResponse) {
            FB.api('/me', { fields: 'name,email,picture' }, (userInfo) => {
                localStorage.setItem('fb_user', JSON.stringify(userInfo));
                router.push('/profile');
            });
        } else {
            toast.warning('You must be logged in.');
        }
    }, { scope: 'public_profile,email' });
};

Conclusion

In this tutorial, you’ve learned how to implement Facebook Login in a Vue 3 application using the Composition API and Vue Router. We walked through setting up a Facebook Developer App, integrating the Facebook SDK, handling authentication and logout, protecting routes, and adding useful enhancements like flash messages and reusable login components. With these tools, you can now build secure and user-friendly social login features in your modern Vue apps. Try extending it further with backend validation, user profiles, or other OAuth providers!

You can find the full source code on our GitHub.

That's just the basics. If you need more deep learning about MEVN Stack, Vue.js, or related, you can take the following cheap course:

Thanks!