Vue works well with Formbase whether you use a standard <form action> or handle submission programmatically. This guide shows a programmatic submission so you can control loading and error state.
Because browser requests receive a 303 redirect, treat that as success in your UI.
Build the form
Create the form fields and bind them to Vue state.
Submit to Formbase
Basic submission
File upload
<script setup>
import { ref } from 'vue';
const status = ref('');
const isSubmitting = ref(false);
const handleSubmit = async (event) => {
event.preventDefault();
status.value = '';
isSubmitting.value = true;
const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
method: 'POST',
body: new FormData(event.currentTarget),
redirect: 'manual',
});
status.value = response.status === 303 || response.ok
? 'Submitted!'
: 'Submission failed.';
isSubmitting.value = false;
};
</script>
<template>
<form @submit="handleSubmit">
<input name="name" placeholder="Name" required />
<input name="email" type="email" placeholder="Email" required />
<textarea name="message" required />
<button type="submit" :disabled="isSubmitting">
{{ isSubmitting ? 'Sending...' : 'Send' }}
</button>
<p v-if="status">{{ status }}</p>
</form>
</template>
FormData mirrors a standard HTML form post.<script setup>
import { ref } from 'vue';
const status = ref('');
const handleSubmit = async (event) => {
event.preventDefault();
const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
method: 'POST',
body: new FormData(event.currentTarget),
redirect: 'manual',
});
status.value = response.status === 303 || response.ok
? 'Uploaded!'
: 'Upload failed.';
};
</script>
<template>
<form @submit="handleSubmit" enctype="multipart/form-data">
<input name="resume" type="file" />
<button type="submit">Upload</button>
<p v-if="status">{{ status }}</p>
</form>
</template>
Add enctype="multipart/form-data" when files are present.
For a JSON response, submit from your server instead of the browser.