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
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>
Part 8: Route Protection with Vue Router Navigation Guards
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:
- Isomorphic JavaScript with MEVN Stack
- Fun Projects with Vue 2
- Learning Path: Vue. js: Rapid Web Development with Vue 2
- Getting Started with Vue JS 2
- Vue. js 2 Recipes
Thanks!