Submitting React form returns entire web page back through AJAX!

Ok, I’ve got a real head scratcher here that’s kept me preoccupied for the past three days. Any help appreciated to help me keep some sanity.

I’ve tried to make a regular, non-complicated form submission and function trigger work through an AJAX submit, but no matter what I do, I seem to be getting the entire web page back in the response . The function never triggers.
I’ve read a thousand posts about getting a 404 back, but I’m actually getting my own page right back in my face.

At first, I thought this was due to some incompatibilty in the UI library I’m using (Chakra), or possibly in the localization library.

However, now I’ve set up a pared down version on my website, and the results are the same.

When developing locally, I’ve sometimes been able to trigger the function, but I have no idea why. It just happens. In production, it just never works.

The original form is here: https://www.sawalist.com/en/jadenaturalspasalon (click review, results are logged to console). This is just prototyping right now, so enter anything in the modal.

The pared down version (code below) is here: https://www.sawalist.com/form_ajax.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Contact</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  </head>
  <body>
    <!-- A little help for the Netlify post-processing bots -->
    <form name="contact" netlify netlify-honeypot="bot-field" hidden>
      <input type="text" name="name" />
      <input type="email" name="email" />
      <textarea name="message"></textarea>
    </form>

    <div id="root"></div>

    <script type="text/babel">
      const encode = (data) => {
        return Object.keys(data)
          .map(
            (key) =>
              encodeURIComponent(key) + "=" + encodeURIComponent(data[key])
          )
          .join("&");
      };

      class ContactForm extends React.Component {
        constructor(props) {
          super(props);
          this.state = { name: "", email: "", message: "" };
        }

        /* Here’s the juicy bit for posting the form submission */

        handleSubmit = (e) => {
          fetch("/", {
            method: "POST",
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            body: encode({ "form-name": "contact", ...this.state }),
          })
            .then(function (response) {
              return response.text().then(function (text) {
                console.log(text);
              });
            })
            .catch((error) => alert(error));

          e.preventDefault();
        };

        handleChange = (e) =>
          this.setState({ [e.target.name]: e.target.value });

        render() {
          const { name, email, message } = this.state;
          return (
            <form netlify netlify-honeypot="bot-field" name="contact" onSubmit={this.handleSubmit}>
              <p>
                <label>
                  Your Name:{" "}
                  <input
                    type="text"
                    name="name"
                    value={name}
                    onChange={this.handleChange}
                  />
                </label>
              </p>
              <p>
                <label>
                  Your Email:{" "}
                  <input
                    type="email"
                    name="email"
                    value={email}
                    onChange={this.handleChange}
                  />
                </label>
              </p>
              <p>
                <label>
                  Message:{" "}
                  <textarea
                    name="message"
                    value={message}
                    onChange={this.handleChange}
                  />
                </label>
              </p>
              <p>
                <button type="submit">Send</button>
              </p>
            </form>
          );
        }
      }

      ReactDOM.render(<ContactForm />, document.getElementById("root"));
    </script>
  </body>
</html>


Hey there, @lecoder :wave:

Thank you so much for writing such a thorough post, and welcome to the Netlify Forums!

I know you shared that you read many posts about getting a 404 back. I just want to confirm, have you also seen our forms debugging article?This Support Guide is the first port of call to debug any forms issues, and sometimes folks miss it when they are searching around.

If you have read that and tried the steps, please let us know the form name that you’ve set and that shows in our UI, and we will continue to look into this issue for you!

Hi there,

I’ve looked through all of these guides - and more - multiple times, unfortunately. I just can’t find a solution.

The form name for the test form - which shows up in the UI on the test page - is “contact”.

Thanks,

Carl

Hi @lecoder,

Before trying to fix AJAX, can you confirm if the form is working correctly without AJAX? Are you able to receive the submissions properly? This would help us remove the obvious guesses out of this, so we can debug accordingly.


Hi,

I set up a non-ajax form here which works: https://www.sawalist.com/form.html

Hi @lecoder

It is the change you made to handleSubmit() that is logging out the text.

The original function had

handleSubmit = e => {
  fetch("/", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: encode({ "form-name": "contact", ...this.state })
  })
    .then(() => alert("Success!"))
    .catch(error => alert(error));

  e.preventDefault();
};

while yours has

handleSubmit = (e) => {
  fetch("/", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: encode({ "form-name": "contact", ...this.state }),
  })
    .then(function (response) {
      return response.text().then(function (text) {
        console.log(text);
      });
    })
    .catch((error) => alert(error));

  e.preventDefault();
};

You are in effect printing out the returned default thank you page when you make the response text().

What you are likely wanting/needing to do check ressponse.ok or response.status. So in your then

.then((res) => console.log(res))

and you will see what response you get.

Hi, and thanks for this. I’ve changed to just printing the result, but I just can’t get it to work - I’m getting 404:s back both from the ajax test form (https://www.sawalist.com/form_ajax.html) and the chakra version on the web page (for instance, https://www.sawalist.com/en/jadenaturalspasalon). However, the pure html version works just fine (https://www.sawalist.com/form.html). I’m pasting the complete ajax test form below:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Contact</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  </head>
  <body>
    <!-- A little help for the Netlify post-processing bots -->
    <form name="contact" netlify netlify-honeypot="bot-field" hidden>
      <input type="text" name="name" />
      <input type="email" name="email" />
      <textarea name="message"></textarea>
    </form>

    <div id="root"></div>

    <script type="text/babel">
      const encode = (data) => {
        return Object.keys(data)
          .map(
            (key) =>
              encodeURIComponent(key) + "=" + encodeURIComponent(data[key])
          )
          .join("&");
      };

      class ContactForm extends React.Component {
        constructor(props) {
          super(props);
          this.state = { name: "", email: "", message: "" };
        }

        /* Here’s the juicy bit for posting the form submission */

        handleSubmit = (e) => {
          fetch("/", {
            method: "POST",
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            body: encode({ "form-name": "contact", ...this.state }),
          })
            .then((res) => console.log(res))
            .catch((error) => alert(error));

          e.preventDefault();
        };

        handleChange = (e) =>
          this.setState({ [e.target.name]: e.target.value });

        render() {
          const { name, email, message } = this.state;
          return (
            <form netlify netlify-honeypot="bot-field" name="contact" onSubmit={this.handleSubmit}>
              <p>
                <label>
                  Your Name:{" "}
                  <input
                    type="text"
                    name="name"
                    value={name}
                    onChange={this.handleChange}
                  />
                </label>
              </p>
              <p>
                <label>
                  Your Email:{" "}
                  <input
                    type="email"
                    name="email"
                    value={email}
                    onChange={this.handleChange}
                  />
                </label>
              </p>
              <p>
                <label>
                  Message:{" "}
                  <textarea
                    name="message"
                    value={message}
                    onChange={this.handleChange}
                  />
                </label>
              </p>
              <p>
                <button type="submit">Send</button>
              </p>
            </form>
          );
        }
      }

      ReactDOM.render(<ContactForm />, document.getElementById("root"));
    </script>
  </body>
</html>

The only error I see with your form is

Warning: Received `true` for a non-boolean attribute `netlify`.

This comes from inside render() where you have

<form netlify netlify-honeypot="bot-field"
  name="contact" onSubmit={this.handleSubmit}>

When copy/pasting your test form below, I received a submission and saw the response logged to the console. I then changed the above the following, and received a submission.

<form onSubmit={this.handleSubmit}>

I received no 404 responses.

Note: This is how the How to Integrate Netlify’s Form Handling in a React App is configured, the netlify and netlify-honeypot attributes only exist in the HTML form which is used by the Netlify bots and hidden when viewing the page, but not used in the react form.

I suggest if you are receiving a 404 still, it is because of the redirect in the response which (one the left) is false for my test, and on the right true for yours.

Hi, and thanks for this. Managed to resolve this, and in case someone ends up with the same problem sometime: it was due to a combination of 1) a redirect library not allowing the POST to go through (added a dummy path as an exception to that plugin to which I now submit) and 2) Chakra UI’s Modal window not rendering the form as HTML, and thereby not being seen by Netlify.

1 Like