> ## 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 + FormKit

> Submit FormKit forms to Formbase.

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.

<Steps>
  <Step title="Wire up the submit handler">
    Use FormKit's `@submit` hook to send data to Formbase.
  </Step>

  <Step title="Send the data">
    <Tabs>
      <Tab title="JSON submission">
        ```vue theme={null}
        <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.
      </Tab>

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

<Callout type="note">
  Use a server-side submit if you need a JSON response from Formbase.
</Callout>
