FormKit handles form state and validation in Vue. You can send the submitted values directly to Formbase as JSON, or switch to FormData when you need file uploads.
Because Formbase returns a 303 redirect to browser requests, treat that status as success in your client-side handler.
Wire up the submit handler
Use FormKit’s @submit hook to send data to Formbase.
Send the data
JSON submission
File upload
<script setup>
import { ref } from 'vue';
const status = ref('');
const handleSubmit = async (data) => {
const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
redirect: 'manual',
});
status.value = response.status === 303 || response.ok
? 'Submitted!'
: 'Submission failed.';
};
</script>
<template>
<FormKit type="form" submit-label="Send" @submit="handleSubmit">
<FormKit name="name" label="Name" validation="required" />
<FormKit name="email" label="Email" validation="required|email" />
<FormKit name="message" type="textarea" label="Message" validation="required" />
</FormKit>
<p v-if="status">{{ status }}</p>
</template>
JSON is ideal when you do not need file uploads.<script setup>
import { ref } from 'vue';
const status = ref('');
const handleSubmit = async (_data, node) => {
const formEl = node.el; // underlying form element
const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
method: 'POST',
body: new FormData(formEl),
redirect: 'manual',
});
status.value = response.status === 303 || response.ok
? 'Uploaded!'
: 'Upload failed.';
};
</script>
<template>
<FormKit type="form" submit-label="Upload" @submit="handleSubmit">
<FormKit name="name" label="Name" validation="required" />
<FormKit name="resume" type="file" label="Resume" />
</FormKit>
<p v-if="status">{{ status }}</p>
</template>
This approach forwards the underlying form element as FormData.
Use a server-side submit if you need a JSON response from Formbase.