Build a Nuxt contact form with $fetch and no server route
A Nuxt contact form can post to FormThunder with $fetch from the browser, so you don't need a Nitro server route, and nuxt generate works fine. Put the access key in public runtime config, and call $fetch inside the submit handler. Don't use useFetch here: it's meant for loading data during setup, and a form submit isn't that.
Updated
The Nuxt code
export default defineNuxtConfig({
runtimeConfig: {
public: { formthunderKey: "YOUR_ACCESS_KEY" },
},
});<script setup lang="ts">
const { formthunderKey } = useRuntimeConfig().public;
const form = reactive({ name: "", email: "", message: "" });
const status = ref<"idle" | "sending" | "sent" | "error">("idle");
async function submit() {
status.value = "sending";
try {
await $fetch("https://formthunder.com/submit", {
method: "POST",
body: { ...form, access_key: formthunderKey },
});
status.value = "sent";
} catch {
status.value = "error";
}
}
</script>
<template>
<form @submit.prevent="submit">
<label>Name <input v-model="form.name" required /></label>
<label>Email <input v-model="form.email" type="email" required /></label>
<label>Message <textarea v-model="form.message" required /></label>
<button :disabled="status === 'sending'">Send</button>
<p v-if="status === 'sent'" role="status">Thanks, we got your message.</p>
<p v-if="status === 'error'" role="alert">That didn't send. Please try again.</p>
</form>
</template>Replace YOUR_ACCESS_KEY with your free key. It's public by design, so it's safe in client code.
Notes for Nuxt
NUXT_PUBLIC_FORMTHUNDER_KEYoverrides the config value at runtime, so you can use a different form per environment without a code change.$fetchsends objects as JSON and throws on a non-2xx reply, so thecatchcovers both network errors and rejected submissions.- If you enable Nuxt's
routeRuleswith CSP headers, allow your FormThunder host underconnect-src.
Or have your AI add it
Connect the MCP server, then ask. The agent creates the form and writes the code for you, and it can send a real test when it's done.
Add a FormThunder contact form to this Nuxt site that emails hello@example.com. Send a test when you're done.Questions
Does this work with nuxt generate?
Yes. The request is made from the browser, so a fully static build works.
Why not useFetch?
useFetch runs during setup and caches for SSR. For an action a person triggers, Nuxt's own docs point you to $fetch.
Get your Nuxt form sending
The free plan covers 250 submissions a month, with MCP, the CLI and the brand kit included.