Netlify Forms with Nuxt3 and Veutify

I have the following code snippet:

<script setup lang="ts">
import { ref } from 'vue'
const route = useRoute()

const valid = ref(false)
const email = ref('')

const emailRules = [
    (value: string) => {
        if (value) return true
        return 'E-mail is required.'
    },
    (value: string) => {
        if (/.+@.+\..+/.test(value)) return true
        return 'E-mail must be valid.'
    }
]

async function handleSubmit() {
    if (valid.value) {
        const subscriptionSubmission = {
            'form-name': 'subscription-form',
            email: email.value,
        }

        // Create a form element
        const form = document.createElement('form')
        form.method = 'POST'
        form.action = `/submission?current_route=${route.path}`
        form.style.display = 'none'
        form.setAttribute('accept-charset', 'UTF-8') // Optional: If needed
        form.setAttribute('enctype', 'application/x-www-form-urlencoded')

        // Append form data as hidden input fields
        for (const [key, value] of Object.entries(subscriptionSubmission)) {
            const input = document.createElement('input')
            input.type = 'hidden'
            input.name = key
            input.value = value as string
            form.appendChild(input)
        }

        // Append form to body and submit
        document.body.appendChild(form)
        form.submit()

        // Cleanup
        document.body.removeChild(form)
    }
}


</script>

<template>
    <v-container fluid class="bg-white d-flex items-center" id="main-container">
        <v-row>
            <v-col cols="3" offset="5" class="text-center">
                <p class="text-h3 anton my-5">STAY UPDATED</p>
                <v-form name="subscription-form" ref="form" data-netlify="true" netlify v-model="valid"
                    @submit.prevent="handleSubmit">
                    <v-row>
                        <v-col cols="8">
                            <v-text-field v-model="email" label="Email Address" class="anton"
                                variant="outlined" :rules="emailRules" name="email" required></v-text-field>
                        </v-col>
                        <v-col cols="4">
                            <v-btn class="anton" color="black" type="submit" style="height:55px;">SUBSCRIBE</v-btn>
                        </v-col>
                    </v-row>
                </v-form>

            </v-col>
        </v-row>
    </v-container>
</template>

This is in the footer on my page. Essentially, when I change the action to “/” it works, but if I pass in another path the submission does not work on Netlify’s side of things. I know I am PROBABLY not doing this the right way but was wondering if there is a way using Nuxt3 & Vuetify to submit a form without navigating off that page.

@Brien What you’re trying to do is submit a form with ajax.

There’s some example documentation here:

https://docs.netlify.com/forms/setup/#submit-html-forms-with-ajax

Hi @nathanmartin, thank’s for getting back so quickly.

I kinda of tweaked it like so & the log messages are stating that it was a succesfull request.:

My Page that has a form:

async function handleSubmit(event) {
  if (valid.value) {
    event.preventDefault();
    const myForm = event.target;
    const formData = new FormData(myForm);
    const success = await submitForm("coach-form", formData);
    console.log(success);
    if (success) {
      submitted.value = true;
    } else {
      failed.value = true;
    }
  }
}

A shared Nuxt3 Util Function:

export async function submitForm(formName: string, formData: Record<string, any>) {
    formData.append('form-name', formName);
    try {
        const response = await fetch('/', {
            method: 'POST',
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            body: new URLSearchParams(formData).toString()
        });

        if (response.ok) {
            console.log('Form submitted successfully');
            return true;
        } else {
            console.error('Form submission failed');
            return false;
        }
    } catch (error) {
        console.error('Error submitting form:', error);
        return false;
    }
}

My Headers & Payload:

This is a link to my app: https://5starfbrecruiting.netlify.app

I’m not quite sure why those results are not being picked up on Netlify’s side of things.

I was able to solve it. From my page components, I had to do something like the following (replace {page} with your route:

async function handleSubmit(event) {
  if (valid.value) {
    event.preventDefault();
    const myForm = event.target;
    const formData = new FormData(myForm);
    const success = await submitForm("/{page}", formData);
    console.log(success);
    if (success) {
      submitted.value = true;
    } else {
      failed.value = true;
    }
  }
}

For my footer component which is rendered across all screens I had to use the base route for my patch

async function handleSubmit(event) {
    if (valid.value) {
        event.preventDefault();
        const myForm = event.target;
        const formData = new FormData(myForm);
        const success = await submitForm("/", formData);
        console.log(success);
        if (success) {
            submitted.value = true;
        } else {
            alert("Subscription failed. Please try again.");
        }
    }
}

This is a shared function I have in utils/submit_form.ts:

export async function submitForm(currentPath: string, formData: Record<string, any>) {
    try {
        const response = await fetch(`${currentPath}`, {
            method: 'POST',
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            body: new URLSearchParams(formData).toString()
        });

        if (response.ok) {
            return true;
        } else {
            return false;
        }
    } catch (error) {
        console.error('Error submitting form:', error);
        return false;
    }
}

Also I had to include hidden inputs in my forms (switching out {my-form-name} for your form name):

<v-text-field type="hidden" name="form-name" value="{my-form-name}"></v-text-field>

And finally I added the following to my nuxt-config.ts:

routeRules: {
    '/': { prerender: true }, # renders the footer form in Netlify Forms
    '/{page_with_form_on_it}': { prerender: true }, # renders the specific page form in Netlify Forms
  }

@Brien The most important part was likely what you did to get the page to be actually output as a static file.

As Netlify’s form handling doesn’t work on routes that are caught by edge functions / middleware.

In the screenshots you provided prior to solving, you can see your submission was being caught by Nuxt.

image

In the request for your working one, you’ll almost certainly not see that.

Thank you for your support @nathanmartin I really do appreciate it!