Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

profnami's avatar

Problem in login with Nuxt3

I just want to create a login form using Laravel and nuxt3. but I get errors that I can't retrieve within a try-catch block.

here are my codes:

<template>
    <div class="container mx-auto w-1/2 py-8">
        <Panel>
            <h3 class="text-2xl font-semibold border-b border-gray-100 pb-4 mb-4">Login to site</h3>
            <form action="#" @submit.prevent="userLogin">
                <div class="mt-2">
                    <label for="title" class="block mb-2">Username:</label>
                    <input type="text" name="username" id="username" class="border border-gray-200 rounded p-1 w-full"
                        v-model="username">
                </div>
                <div class="mt-2">
                    <label for="body" class="block mb-2">Password:</label>
                    <input type="password" name="password" id="password" class="border border-gray-200 rounded p-1 w-full"
                        v-model="password">
                </div>
                <div>
                    <p class="text-xs text-red-500">
                    <ul v-if="errors.length > 0">
                        <li v-for="(error, index) in errors" :key="index">
                            {{ error }}
                        </li>
                    </ul>

                    </p>
                </div>
                <div class="mt-2">
                    <button type="submit" class="bg-blue-500 hover:bg-blue-600 rounded text-white px-3 py-1">Login</button>
                </div>
            </form>
        </Panel>
    </div>
</template>

<script setup>

import Cookie from 'js-cookie'

const username = ref('')
const password = ref('')
const errors = ref([])
const config = useRuntimeConfig();

function csrf() {
    return useFetch(config.BASE_URL + '/sanctum/csrf-cookie', {
        credentials: 'include'
    })
}

async function userLogin() {
    await csrf()
    try {
        await useFetch(config.BASE_URL + '/login', {
            method: 'POST',
            credentials: 'include',
            headers: {
                Accept: 'application/json',
                'X-XSRF-TOKEN': Cookie.get('XSRF-TOKEN')
            },
            body: {
                username: username.value,
                password: password.value
            }
        })
    } catch (error) {
        console.log(error.data)
        errors.value = Object.values(error.data.errors).flat()
    }
}
</script>

and here is the error code :

Status Code: 422 Unprocessable Content

How can I read these errors in the catch section and show them to the user?

0 likes
1 reply
LaryAI's avatar
Level 58

The error code 422 indicates that there is an issue with the data submitted in the request. In this case, it seems like there might be validation errors with the username and password fields. To retrieve and display these errors, you can modify the catch block in the userLogin function as follows:

async function userLogin() {
  await csrf()
  try {
    await useFetch(config.BASE_URL + '/login', {
      method: 'POST',
      credentials: 'include',
      headers: {
        Accept: 'application/json',
        'X-XSRF-TOKEN': Cookie.get('XSRF-TOKEN')
      },
      body: {
        username: username.value,
        password: password.value
      }
    })
  } catch (error) {
    if (error.response.status === 422) {
      errors.value = Object.values(error.response.data.errors).flat()
    } else {
      console.log(error)
    }
  }
}

Here, we check if the error response status is 422, and if so, we retrieve the validation errors from the response data and assign them to the errors ref. We also added an else block to log any other errors that might occur.

Note that we are accessing the response data using error.response.data instead of error.data, since the error object returned by useFetch includes a response property that contains the response data.

With this modification, the validation errors should be displayed in the template as a list under the password field.

Please or to participate in this conversation.