Part 6 - How to build a Login system in Vue 3 for Laravel Sanctum API
By Ved Prakash N |
Jul 08, 2026 |
Vue JS
This is the source code for the YouTube video.
How to build a Login system in Vue 3 for Laravel Sanctum API using AI ChatGPT
Create Auth Composable
create a file useAuth.js at following path - src/composables/useAuth.js
import { ref } from "vue";
import axios from "axios";
const user = ref(null);
export function useAuth() {
const loading = ref(false);
const errors = ref({});
const getUser = async () => {
try {
const { data } = await axios.get("/api/user");
user.value = data;
} catch {
user.value = null;
}
};
const login = async (credentials) => {
loading.value = true;
errors.value = {};
try {
await axios.get("/sanctum/csrf-cookie");
await axios.post("/login", credentials);
await getUser();
return true;
} catch (error) {
if (error.response?.status === 422) {
errors.value = error.response.data.errors;
}
if (error.response?.status === 401) {
errors.value = {
email: ["Invalid credentials."]
};
}
return false;
} finally {
loading.value = false;
}
};
const logout = async () => {
await axios.post("/logout");
user.value = null;
};
return {
user,
loading,
errors,
login,
logout,
getUser
};
}
Create Login page
Create a file Login.vue at following path - src/views/auth/Login.vue and paste the below code
<template>
<div class="min-h-screen flex items-center justify-center bg-gray-100">
<div class="w-full max-w-md bg-white p-8 rounded-xl shadow">
<h1 class="text-3xl font-bold mb-6 text-center">
Login
</h1>
<form @submit.prevent="submit">
<div class="mb-4">
<label>Email</label>
<input
v-model="form.email"
type="email"
class="w-full border rounded p-3 mt-1"
/>
<p
v-if="errors.email"
class="text-red-500 text-sm mt-1"
>
{{ errors.email[0] }}
</p>
</div>
<div class="mb-4">
<label>Password</label>
<input
v-model="form.password"
type="password"
class="w-full border rounded p-3 mt-1"
/>
<p
v-if="errors.password"
class="text-red-500 text-sm mt-1"
>
{{ errors.password[0] }}
</p>
</div>
<button
:disabled="loading"
class="w-full bg-blue-600 text-white p-3 rounded disabled:bg-gray-400"
>
<span v-if="loading">
Logging in...
</span>
<span v-else>
Login
</span>
</button>
</form>
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import { useRouter } from "vue-router";
import { useAuth } from "@/composables/useAuth";
const router = useRouter();
const {
login,
loading,
errors
} = useAuth();
const form = reactive({
email: "",
password: ""
});
const submit = async () => {
if (!form.email || !form.password) {
errors.value = {};
if (!form.email)
errors.value.email = ["Email required"];
if (!form.password)
errors.value.password = ["Password required"];
return;
}
const success = await login(form);
if (success) {
router.push("/dashboard");
}
};
</script>
Create Dashboard page
Create a file Dashboard.vue at following path - src/views/users/Dashboard.vue and paste the below code
<template>
<div class="min-h-screen bg-gray-100">
<nav class="bg-white shadow p-4 flex justify-between">
<h1 class="font-bold">
Dashboard
</h1>
<button
@click="logoutUser"
class="bg-red-500 text-white px-4 py-2 rounded"
>
Logout
</button>
</nav>
<div class="p-10">
<h2 class="text-2xl">Welcome {{ user?.name }}</h2>
</div>
</div>
</template>
<script setup>
import { onMounted } from "vue";
import { useRouter } from "vue-router";
import { useAuth } from "@/composables/useAuth";
const router = useRouter();
const {
logout,
getUser,
user
} = useAuth();
onMounted(async () => {
await getUser();
});
const logoutUser = async () => {
await logout();
router.push("/login");
};
</script>
Add the routes for the above pages login and dashboard for example:-
{
path: "/login",
name: "login",
component: Login,
meta: {
guest: true
}
},
{
path: "/dashboard",
name: "dashboard",
component: Dashboard,
meta: {
auth: true
}
}
Please continue to watch above Youtube Video to understand better.