Developing a Netlify Contact Form using Alpine.js
The most common request to a simple landing or a simple company web page is to provide a simple contact form. A simple feature to add, isn’t it? Well, not so much. For a simple static web deployment, you need to provide a backend infrastructure with email support. Fortunately, there is an easy solution for it.
What is the Netlify?
Netlify is a service platform that provides static deployment to your website with many features such as custom domains, https, git deployment, serverless functions, and for us, a form service.
How does it work?
For a simple HTML form, append the
netlify attribute to its form tag:
<form name="contact" netlify> .... </form>
Then, every time a user submits the form, it will be intercepted from Netlify, the form info will appear in your site dashboard, and the user will be directed to a success page. Furthermore, it may be configured to notify yourself of the submissions using email or any webhook and add three-level spam filtering.
The spam prevention systems consist of:
a spam detection system,
an optional honeypot field, which is a hidden form field that lures bot users into completing a field that human users can’t see, and
an optional reCAPTCHA spam prevention.
The first takeout from the above code is how to compose the
<form name="contact" method="POST" data-netlify="true" netlify-honeypot="bot-field" data-netlify-recaptcha="true">
We named the form (
name="contact"), we defined it as netlify form with the
data-netlify="true" attribute and add two optional spam-prevention layers: the honeypot (
netlify-honeypot="bot-field") and the Google reCAPTCHA 2 (
netlify-honeypot attribute is working by adding a hidden input form element, which will be submitted as empty:
<p hidden><label>ignore: <input name="bot-field" /></label></p>
The idea behind this spam-prevention schema is that a bot will see the input element, and it will fill it. Therefore, if the form is submitted with a non-empty value, then it will be rejected. Take note that the name of the honeypot
bot-field can be anything; just defined it in the
The Google reCAPTCHA 2 will be showing up by adding the following inside the
The above code will work on any HTML page that is deploying in the netlify server. In fact, by using the html5 form validation attributes, it can provide client-based form validation, too.
The installation is simple enough just add a script to the end of your
<script src="https://firstname.lastname@example.org/dist/alpine.min.js" defer></script>
These distinct characteristics make it more suitable for jQuery replacement for smaller tasks than Vue.
For more information, you may check our introductory article about Alpine.js.
Initially, we recreate the HTML-only form code and hide it. The hidden form acts as a stand-in for the Alpine.js form component, so the netlify bot understands what to expect to receive from the fetch submission.
Next, we initialize our component using
x-data with the required data object for form validation.
x-data attribute plays the same role as the
data Vue component property. The data object properties, as in Vue, are reactive.
x-on attaches an event listener to the form
Next, to validate and check the value of an input form element component, the following code is used:
<p><label>Full Name: <input x-model="name" x-on:blur="nameDirty = true" type="text" name="name"/></label></p> <p x-show.transition="nameDirty && name.length == 0" style="color: red" x-cloak> Please fill out your full name. </p>
x-model attribute adds a “two-way data binding” to the input element. Consequently, the input element’s value will be in sync with the name variable in the data object. When the input lost focus, the
nameDirty variable is updated as
nameDirty is true and the name variable is empty, a warning message is shown using the
x-show attribute. The
x-show attribute toggles the
display: none; style attribute on the element depending on the expression output.
transition directive is a convenience API offered by Alpine.js, which applies CSS transitions to the element. From the documentation, the
transition directive is a simultaneous fade and scale:
opacity, scale: 0.95, timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), duration-in: 150ms, duration-out: 75ms
submitMessage takes as input the contents of
message variables, validate them, and if it is correct, it submits the form contents using the fetch API.
Note that the AJAX request’s content must be URL-encoded, as the Netlify forms do not support JSON form data currently. The URL-encoded form can be easily created by using the URLSearchParams utility method:
let formElement = document.getElementById("contact"); let body = new URLSearchParams(new FormData(formElement)).toString();
The final complete
submitMessage function is:
The final code using Alpine.js for client-based form input validation and sending the form to netlify using the Fetch API is:
Altogether, I think the Netlify form simplifies the usage of form in your web page. Of course, under the assumption to host your web app in their hosting service.