Contact form for Vue and Nuxt
A Vue contact form is a template, a reactive status ref, and one fetch call. The same component works in Vite-powered Vue SPAs and in Nuxt (including nuxt generate static sites) because nothing here needs a server.
ContactForm.vue
<script setup>
import { ref } from "vue";
const status = ref("idle");
async function onSubmit(e) {
status.value = "sending";
const data = Object.fromEntries(new FormData(e.target));
const res = await fetch("https://formdock.app/f/your-form-key", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
status.value = res.ok ? "sent" : "error";
}
</script>
<template>
<p v-if="status === 'sent'">Thanks — we got your message.</p>
<form v-else @submit.prevent="onSubmit">
<input name="name" required placeholder="Name" />
<input name="email" type="email" required placeholder="Email" />
<textarea name="message" placeholder="Message"></textarea>
<button :disabled="status === 'sending'">Send</button>
<p v-if="status === 'error'">Something went wrong — try again.</p>
</form>
</template>- In Nuxt, put the endpoint in runtimeConfig.public and read it with useRuntimeConfig() instead of hardcoding.
- FormData picks up every named input automatically — add fields to the template and they arrive in your dashboard without code changes.
- The submitter's email field becomes the Reply-To on your notification email.
Get your endpoint: create a free FormDock account (100 submissions/month), add a form, and swap your-form-key for the real key.