How to create a Vue.js contact form
Build a Vue.js contact form that collects submissions with no backend. Copy-paste examples for a plain form and a Vue 3 script-setup submission with success and error states.
Vue.js is a popular framework for building web user interfaces. This guide shows you how to add a Vue.js contact form that collects submissions and emails you on every new one — without writing or hosting any backend code. We’ll start with a plain form and then enhance it with Vue 3’s Composition API to submit in the background and show an inline confirmation.
Create your form endpoint in FormBackend
Go create a login and create a new form endpoint in FormBackend. Give it a name you can remember for example: “Vue Contact Form” or something similar for this tutorial. It can always be changed later and is only used for you to remember your form.
Create a new Vue.js app
We’ll start from scratch by creating a new Vue.js app. If you already have one you can skip to the next step. We’re basically following what the Vue.js quickstart guide does.
Go ahead and run the following in your terminal
npm create vue@latest
This will run create-vue which will ask you some questions about how you want to setup your application. It doesn’t really have any impact on how we’re going to do things with FormBackend so pick
whatever you’re the most comfortable with.
Go to the new directory of your app, ours is called formbackend-vuejs
cd formbackend-vuejs
Let’s install the dependencies
npm install
and start the local development web server
npm run dev
If you visit the URL it prints (http://localhost:5173) you should see the following:

Create a contact form endpoint in FormBackend
Log in to your FormBackend account and visit the forms index page. Go ahead and create a new form and give it a name you can remember it by.
After your form has been created, you’ll see the “Submissions” page which is where new submissions will appear. If you navigate to the “Set up” page you can see the unique URL for your form. We’ll copy that!
Add the contact form to your Vue.js app
Now that we have the form endpoint in FormBackend, we can add the form to your Vue.js app. Open up src/App.vue and replace everything with:
We’ll add the following code to it:
<template> <main> <h1>Contact Form</h1> <form action="https://www.formbackend.com/f/{your-identifier}" method="POST"> <div class="form-fields"> <label for="name">Name</label> <input type="text" id="name" name="name" required> </div> <div class="form-fields"> <label for="email">Email</label> <input type="email" id="email" name="email" required> </div> <div class="form-fields"> <label for="message">Message</label> <textarea id="message" name="message" required></textarea> </div> <button type="submit">Send message</button> </form> </main> </template> <style scoped> h1 { font-size: 1.8rem; font-weight: bold; margin-bottom: 1rem; } .form-fields { margin-bottom: 1rem; } label { display: block; margin-bottom: 4px; font-weight: bold; font-size: 0.9rem; } input[type="text"], input[type="email"], textarea { border: 1px solid #ccc; font-size: 1rem; padding: 6px 10px; border-radius: 4px; } button[type="submit"] { background-color: rgb(67 56 202); color: white; font-size: 0.8rem; border: none; border-radius: 4px; padding: 8px 12px; font-weight: 500; } </style>
Notice the action-attribute on the form itself, you need to paste in the unique URL for your form that you copied in the previous step and paste that in here.
This form only has three fields. But you can add as many or as few as you want. As long as they have a unique name attribute which is how we store them in our database and how you can recognize the fields
when you view a submission.
If you visit http://localhost:5173 in your browser you should see your form:

After filling it out and hitting the submit button, you’ll be taken to FormBackend’s submission success page. If you navigate to the Submissions tab for the form you created in FormBackend earlier you should see the submission you just added.
Submitting without a page refresh
The form above works on its own, but it redirects to a thank-you page on submit. To keep
users on the page and show an inline confirmation, submit it in the background with Vue 3’s
Composition API. Replace src/App.vue with:
<script setup> import { ref } from 'vue' const status = ref('idle') async function handleSubmit(event) { status.value = 'submitting' const form = event.target const response = await fetch(form.action, { method: 'POST', body: new FormData(form), headers: { accept: 'application/json' }, }) if (response.ok) { form.reset() status.value = 'success' } else { status.value = 'error' } } </script> <template> <main> <h1>Contact Form</h1> <p v-if="status === 'success'">Thanks! Your message has been sent.</p> <form v-else action="https://www.formbackend.com/f/{your-identifier}" method="POST" @submit.prevent="handleSubmit" > <div class="form-fields"> <label for="name">Name</label> <input type="text" id="name" name="name" required> </div> <div class="form-fields"> <label for="email">Email</label> <input type="email" id="email" name="email" required> </div> <div class="form-fields"> <label for="message">Message</label> <textarea id="message" name="message" required></textarea> </div> <button type="submit" :disabled="status === 'submitting'"> {{ status === 'submitting' ? 'Sending…' : 'Send message' }} </button> <p v-if="status === 'error'">Something went wrong — please try again.</p> </form> </main> </template>
How it works:
- The
@submit.preventmodifier stops the browser’s default full-page submission, so you don’t need to callevent.preventDefault()yourself. - The browser’s built-in
FormDatareads every field from the form, so you don’t need arefper input. - The
accept: application/jsonheader tells FormBackend to return JSON instead of an HTML page. - The
statusref drives the UI withv-if/v-else— the form is swapped for a thank-you message once the submission succeeds.
Notifications and integrations
With your Vue.js form collecting submissions, you can:
- Get email notifications: Receive an email with submission data (including file attachments) every time someone submits
- Send auto-reply emails: Let submitters know you received their message with a customizable email template
- Filter spam: Submissions are spam-checked automatically. Add Cloudflare Turnstile or hCaptcha for stronger protection
- Connect integrations: Route submissions to Slack, Google Sheets, Notion, Discord, or any URL via webhooks
- Customize the thank-you page or redirect users to a specific page on your site
Guides for other frameworks: Nuxt, React, Next.js, Svelte, Astro, and more.
Add a form backend to your site in minutes
Connect any HTML form to FormBackend and start collecting submissions — no backend code required.
Start free