Working With Forms In Gridsome & Netlify

Working With Forms In Gridsome & Netlify

The main reason I love python is its simplicity. Infact its so straightforward that it actually influenced how I live from day to day. There's this thing called the Zen Of Python by Tim Peters. One of its primers is that explicit is better than implicit.

This, however, is a post about a Vue.js framework called Gridsome and how its forms can be integrated with Netlify which is a JAMStack platform. I make the python reference because in trying to implement a form on Gridsome to submit to Netlify by following the tutorials on their page, it wasn't explicit as one would have expected it to be.

Now let's have a look at the code on their site that explains this implementation .

<form 
  name="contact"
  method="post"
  v-on:submit.prevent="handleSubmit"
  action="/success/"
  data-netlify="true"
  data-netlify-honeypot="bot-field"
>
  <input type="hidden" name="form-name" value="contact" />
  <p hidden>
    <label>
      Don’t fill this out: <input name="bot-field" />
    </label>
  </p>
  <div class="sender-info">
    <div>
      <label for="name" class="label" >Your name</label>
      <input type="text" name="name" v-model="formData.name" />
    </div>
    <div>
      <label for="email">Your email</label>
      <input type="email" name="email" v-model="formData.email" />
    </div>
  </div>

  <div class="message-wrapper">
    <label for="message">Message</label>
    <textarea name="message" v-model="formData.message"></textarea>
  </div>

  <button type="submit">Submit form</button>
</form>

This is the html part of the vue page. In order for the methods and v-directives to take effect, there's a JavaScript section shown below.

<script>
export default {
  data() {
    return {
      formData: {},
    }
},

  methods: {
  encode(data) {
    return Object.keys(data)
      .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
      .join('&')
  },
  handleSubmit(e) {
    fetch('/', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: this.encode({
        'form-name': e.target.getAttribute('name'),
        ...this.formData,
      }),
    })
    .then(() => this.$router.push('/success'))
    .catch(error => alert(error))
  }
}
};
</script>

This looks syntactically correct except that it wasn't delivering the form data to the Netlify backend even though the form name was showing up. Then the debugging started. How do you debug something that looks correct? After a bit of searching, I found this on the Netlify forums

form_debug.png

Point number 2 meant that the addition of the following line in the html would create the problem at point number 5 on the list.

<input type="hidden" name="form-name" value="contact" />

In other words we were creating a duplicate entry which would result in the form data not showing up in the Netlify backend. Imagine the head scratching moments leading up to this discovery. I hope this post helps someone else.

The official documentation should be the single source of truth and errors like this shouldn't have to be debugged. Anyways like I said in the beginning of this post, explicit is better than implicit. Welcome to the Zen of Gridsome!