How to prevent Netlify form from redirecting on submit (React)

Hey folks,

I’m using Netlify Forms with a React app (SPA) and want to submit the form without a page reload or redirect — show a toast message on the same page.

Website link (scroll down on the home page to the ‘Reach out to us’ section to find the form)

Relevant code:

<form
  name="contact"
  method="POST"
  netlify
  data-netlify="true"
  netlify-honeypot="bot-field"
>
  <input type="hidden" name="form-name" value="contact" />
  <p className="hidden">
    <label>
      Don’t fill this out if you’re human: <input name="bot-field" />
    </label>
  </p>

  {/* input fields... */}

  <input type="submit" value="Submit" />
</form>

What happens here is that it shows a “Page not found error page”, and the network tab shows 404 not found, reference image for both:

What I want:

  • Netlify to process the form
  • No redirect or full page reload
  • Toast shows on the same page

I have already tried action “/” & “#”

There already was a similar question on this forum, but since there was no concrete solution to that, I figured I’d raise the query again. This solution does not work either.

Any help or best practice guidance appreciated!

@kushalv238 Netlify has documentation for precisely this:

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

To prevent the 404:

  • Ensure your form exists in HTML (not only in JavaScript)
  • Enable form detection for the site
  • Do a fresh deploy after enabling form detection
  • Check the deploy log / Netlify UI to confirm that the form was detected
  • Ensure your submission payload contains the form-name

Hey @nathanmartin, thank you for the reply, but unfortunately, this doesn’t work either. I tried the exact code provided in the documentation, and I am still getting a 404 error.

This is what i wrote:

const [formSubmitted, setFormSubmitted] = useState(false);

const handleSubmit = async (event) => {
    event.preventDefault();

    const form = event.target;
    const formData = new FormData(form);

    try {
        await fetch("/", {
            method: "POST",
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            body: new URLSearchParams(formData).toString(),
        });
        setFormSubmitted(true);

        form.reset();
        toast.success("Thanks! We'll be in touch soon.");
    } catch (error) {
        toast.error("Oops! Something went wrong.");
        console.error("Form submission error:", error);
    }
};

Form:

<form
    name="contact"
    method="POST"

    data-netlify="true"
    netlify-honeypot="bot-field"

    onSubmit={handleSubmit}
>

    {/* honeypot trap */}
    <p class="hidden">
        <label>
            Don’t fill this out if you’re human: <input name="bot-field" />
        </label>
    </p>

    {/* hidden field required by Netlify */}
    <input type="hidden" name="form-name" value="contact" />

    {/* all input fields*/}

    <div className="w-full flex">
        <input className='w-full lg:w-auto application-button cursor-pointer' type="submit" value="Submit" />
    </div>
</form>

This just gives a toast success message, but 404 in the network tab (same as before).

While form detection is enabled in Netlify, the section " Usage and configuration; General information and configuration about your Netlify Forms" is stuck on load. Could that be an issue?

Relevant screenshot:

I’m confident it does, and I suspect that you haven’t done the first check I mentioned:

The related documentation is:
https://docs.netlify.com/forms/setup/#forms-for-next-js-or-ssr-frameworks

If you’re using a pure JavaScript form or SSR (Server Side Rendering), you must include an HTML form that meets this HTML form criteria, including all the input tags with the same names as the JavaScript form.

Netlify scans your HTML files post-build to locate forms.
It won’t see any forms that are only created at runtime via JavaScript.
The example of your form you’ve provided above is react, and thus JavaScript.
It’s not in the HTML source of the page:

You either need to put it in that page hidden, or on some other page so it can be found.