PRACTICAL 10: CLIENT-SIDE AND SERVER-SIDE FORM VALIDATION USING NUXT 3

```

npm create nuxt@latest p10
cd p10
npm install
npm run dev

```

server/api/register.post.js

```

export default defineEventHandler(async (event) => {
  const data = await readBody(event)
  const errors = {}

  if (!data.name?.trim())
    errors.name = 'Name is required'

  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email || ''))
    errors.email = 'Invalid email'

  if (!/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{8,}$/.test(data.password || ''))
    errors.password = 'Password must contain 8 characters, uppercase, lowercase and number'

  if (!/^\d{10}$/.test(data.phone || ''))
    errors.phone = 'Phone must contain 10 digits'

  if (Object.keys(errors).length)
    throw createError({
      statusCode: 400,
      statusMessage: 'Validation failed',
      data: { errors }
    })

  return { message: 'Registration successful!' }
})

```

pages/index.vue

```

<script setup>
const form = reactive({
  name: '',
  email: '',
  password: '',
  phone: ''
})

const errors = ref({})
const message = ref('')

function validate() {
  errors.value = {}

  if (!form.name.trim())
    errors.value.name = 'Name is required'

  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email))
    errors.value.email = 'Enter valid email'

  if (!/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{8,}$/.test(form.password))
    errors.value.password = 'Minimum 8 characters with uppercase, lowercase and number'

  if (!/^\d{10}$/.test(form.phone))
    errors.value.phone = 'Enter 10 digit phone number'

  return Object.keys(errors.value).length === 0
}

async function submit() {
  message.value = ''
  if (!validate()) return

  try {
    const res = await $fetch('/api/register', {
      method: 'POST',
      body: form
    })
    message.value = res.message
    Object.assign(form, { name: '', email: '', password: '', phone: '' })
  } catch (e) {
    errors.value = e.data?.data?.errors || {}
    message.value = 'Registration failed!'
  }
}
</script>

<template>
  <main class="container">
    <h1>Registration Form</h1>

    <form @submit.prevent="submit">
      <input v-model="form.name" placeholder="Full Name">
      <p v-if="errors.name" class="error">{{ errors.name }}</p>

      <input v-model="form.email" placeholder="Email">
      <p v-if="errors.email" class="error">{{ errors.email }}</p>

      <input v-model="form.password" type="password" placeholder="Password">
      <p v-if="errors.password" class="error">{{ errors.password }}</p>

      <input v-model="form.phone" placeholder="Phone Number">
      <p v-if="errors.phone" class="error">{{ errors.phone }}</p>

      <button type="submit">Register</button>
    </form>

    <p v-if="message" class="success">{{ message }}</p>
  </main>
</template>

```

nuxt.config.ts

```

export default defineNuxtConfig({
  compatibilityDate: '2025-01-01'
})

```

assets/css/main.css

```

body {
  margin: 0;
  font-family: Arial, sans-serif;
  background: #eef2ff;
}
.container {
  max-width: 420px;
  margin: 50px auto;
  padding: 30px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 5px 20px #0002;
}
h1 { text-align: center; color: #4f46e5; }
input {
  width: 100%;
  padding: 12px;
  margin: 8px 0;
  box-sizing: border-box;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
}
button {
  width: 100%;
  padding: 12px;
  background: #4f46e5;
  color: white;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}
.error { color: red; font-size: 13px; }
.success { color: green; text-align: center; }

```

nuxt.config.ts — Add CSS configuration:

```

export default defineNuxtConfig({
  css: ['~/assets/css/main.css']
})

```

Terminal

```

npm run dev

```

Browser

```

http://localhost:3000

```

Client-side vs Server-side Validation

```

Client-side validation:
Validation happens in the browser before sending data to the server.
It provides immediate error messages and improves user experience.

Server-side validation:
Validation happens on the backend after receiving the request.
It protects the application because client-side validation can be bypassed.

Both validations are important for secure form submission.

```