Beginner5 minUpdated Mar 27, 2026

How to Add a Contact Form to Vue.js

Add a fully functional contact form to your Vue.js app using v-model bindings and fetch. No backend server required — FormsList handles everything.

Prerequisites

  • A Vue.js project (Vue 3 recommended)
  • A FormsList account (free)
  • Basic knowledge of Vue Composition API

TL;DR

To add a contact form to Vue.js, create a component with v-model bindings and submit via fetch to `https://formslist.com/f/your-form-id`. FormsList handles storage, notifications, and spam protection — no backend server required.

1

Create a FormsList form endpoint

Sign up for a free FormsList account and create a new form. Copy the unique endpoint URL from your dashboard — you will use it as the fetch URL in your Vue component.

// Your endpoint will look like this:
// https://formslist.com/f/YOUR_FORM_HASH
2

Build the Vue contact form component

Create a new single-file component using the Composition API with <script setup>. We use reactive refs for each field and a status ref to manage submission state. The handleSubmit function sends form data to FormsList via fetch.

<script setup lang="ts">
import { ref } from 'vue'

const name = ref('')
const email = ref('')
const message = ref('')
const status = ref<'idle' | 'sending' | 'sent' | 'error'>('idle')

async function handleSubmit() {
  status.value = 'sending'

  const formData = new FormData()
  formData.append('name', name.value)
  formData.append('email', email.value)
  formData.append('message', message.value)

  try {
    const res = await fetch('https://formslist.com/f/YOUR_FORM_HASH', {
      method: 'POST',
      body: formData,
    })

    if (res.ok) {
      status.value = 'sent'
      name.value = ''
      email.value = ''
      message.value = ''
    } else {
      status.value = 'error'
    }
  } catch {
    status.value = 'error'
  }
}
</script>

<template>
  <form @submit.prevent="handleSubmit" class="space-y-4 max-w-md">
    <div>
      <label for="name" class="block text-sm font-medium">Name</label>
      <input
        id="name"
        v-model="name"
        type="text"
        required
        class="mt-1 block w-full rounded border p-2"
      />
    </div>
    <div>
      <label for="email" class="block text-sm font-medium">Email</label>
      <input
        id="email"
        v-model="email"
        type="email"
        required
        class="mt-1 block w-full rounded border p-2"
      />
    </div>
    <div>
      <label for="message" class="block text-sm font-medium">Message</label>
      <textarea
        id="message"
        v-model="message"
        rows="4"
        required
        class="mt-1 block w-full rounded border p-2"
      />
    </div>
    <button
      type="submit"
      :disabled="status === 'sending'"
      class="rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700 disabled:opacity-50"
    >
      {{ status === 'sending' ? 'Sending...' : 'Send Message' }}
    </button>
    <p v-if="status === 'sent'" class="text-green-600">Message sent successfully!</p>
    <p v-if="status === 'error'" class="text-red-600">Something went wrong. Please try again.</p>
  </form>
</template>
3

Add the component to your page

Import and use your ContactForm component in any Vue page or parent component. If you are using Vue Router, create a /contact route that renders this component.

<script setup>
import ContactForm from '@/components/ContactForm.vue'
</script>

<template>
  <main class="mx-auto max-w-2xl py-12 px-4">
    <h1 class="text-3xl font-bold mb-6">Contact Us</h1>
    <ContactForm />
  </main>
</template>
4

Test and configure notifications

Submit a test message and check your FormsList dashboard to confirm it arrived. Enable email notifications, set up auto-responders, or connect integrations like Slack and Google Sheets from the dashboard.

Frequently Asked Questions

Ready to collect form submissions?

Set up your form backend in under a minute. No server required, no complex configuration — just a simple endpoint for your forms.