# Add a contact form to a Nuxt site

> Handle Nuxt form submissions with SiteBackend. Works with static generation (nuxt generate) - no server routes needed.

Source: https://sitebackend.com/docs/forms/nuxt · Updated: 2026-10-09

SiteBackend receives the form, so it works with `nuxt generate` and any static host.

```vue title="components/ContactForm.vue"
<script setup lang="ts">
const endpoint = useRuntimeConfig().public.sitebackendForm;
const status = ref<"idle" | "sending" | "sent" | "error">("idle");
const error = ref("");

async function onSubmit(event: Event) {
  status.value = "sending";
  const form = event.target as HTMLFormElement;
  const result = await $fetch<{ ok: boolean; error?: string }>(endpoint, {
    method: "POST",
    body: new FormData(form),
    headers: { Accept: "application/json" },
  }).catch((e) => e.data);
  if (result?.ok) status.value = "sent";
  else {
    error.value = result?.error ?? "Something went wrong";
    status.value = "error";
  }
}
</script>

<template>
  <p v-if="status === 'sent'">Thanks! We'll be in touch.</p>
  <form v-else :action="endpoint" method="POST" @submit.prevent="onSubmit">
    <input type="email" name="email" required />
    <textarea name="message" required />
    <button type="submit" :disabled="status === 'sending'">Send</button>
    <p v-if="status === 'error'" role="alert">{{ error }}</p>
  </form>
</template>
```

```ts title="nuxt.config.ts"
export default defineNuxtConfig({
  runtimeConfig: {
    public: { sitebackendForm: "" }, // set NUXT_PUBLIC_SITEBACKEND_FORM
  },
});
```

The form keeps its `action`, so it still works without JavaScript. If you use [allowed origins](https://sitebackend.com/docs/forms/allowed-origins), add `http://localhost:3000` for local development.

## Show testimonials too

SiteBackend can also collect testimonials from your customers and show them on your site. See add testimonials to a Nuxt site.
