Part 6 - How to build a Login system in Vue 3 for Laravel Sanctum API

By Ved Prakash N | Jul 08, 2026 | Vue JS
Share :

https://www.fundaofwebit.com/post/part-6-how-to-build-a-login-system-in-vue-3-for-laravel-sanctum-api

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.

https://www.fundaofwebit.com/post/part-6-how-to-build-a-login-system-in-vue-3-for-laravel-sanctum-api

Share this blog on social platforms