> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formbase.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Vue (Vanilla)

> Submit to Formbase from a Vue component.

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.

<Steps>
  <Step title="Build the form">
    Create the form fields and bind them to Vue state.
  </Step>

  <Step title="Submit to Formbase">
    <Tabs>
      <Tab title="Basic submission">
        ```vue theme={null}
        <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.
      </Tab>

      <Tab title="File upload">
        ```vue theme={null}
        <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.
      </Tab>
    </Tabs>
  </Step>
</Steps>

<Callout type="note">
  For a JSON response, submit from your server instead of the browser.
</Callout>
