Netlify Contact Form with React Ant Design Form Components
Using a Netlify form should be dead simple. The documentation isn’t very thorough and they are doing a lot in the background that you usually don’t need to know but when things go wrong it sure would have been nice to see some documentation.
Skip ahead
The full code and an interactive demo are at the bottom of the page.
What we are building
We’re building a simple contact form with three fields — name, email, message.
It will be a React component that uses the Ant Design components to display a Netlify form.
The setup
React 16.13
GatsbyJS 2.19
Ant Design 4.1
ES6
I’m using Gatsby in this case but this tutorial doesn’t refer to any Gatsby specifics. It should be fine for any project using Ant Design React Components and Netlify forms.
How does Netlify know about your form?
It’s important to know how Netlify is working in the background to detect your form so we can give it exactly what it wants.
After you deploy your project to Netlify, they run post processing scripts to find any forms on your site. If they find one, the form will show up in the forms section of your Netlify account.
Important: Your form will will not work on localhost. It must be deployed to Netlify to receive submissions.
Create the component
In this example we are using functional React so let’s define the component.
Create a new file called NetlifyContactForm.js
We’re going to need to use the form name in a couple of places so lets define it as a constant. The form name will be used by Netlify to give your form a name in your Netlify account. If you change this name in the future, Netlify will create a new form with the new name.
At this time, we’ll also add our imports and create a base for our layout with a row and column. This will center our form on the page.
import React from 'react'
import { Row, Col, Button, Form, Input } from 'antd'
const { TextArea } = Input
import { UserOutlined, MailOutlined } from '@ant-design/icons' const NetlifyContactForm = () => {
const formName = `contact`
return (
<Row justify="space-around" >
<Col xs={22} sm={18} md={16} lg={8} >
{/* TODO: add form here */}
</Col>
</Row>
)
} export default NetlifyContactForm
Add a shadow html form for Netlify
You might think, all I need to do is add a form with Ant Design components and give it the form name and it will all work fine. This will lead to much pain and suffering. Netlify will not recognize your form correctly.
Ant forms don’t render the field name on the input itself and this causes problems when Netlify searches for your form. Instead of trying to hack around that, we will just provide a hidden html version of the form on the page. This is only for the Netlify bots to use so we’ve marked it as hidden.
Think of this as defining your form for Netlify. Notice that we set the form name to use the `formName` constant. This will tell Netlify to use that name when creating the form.
{/* This defines how your form is setup for the Netlify bots. Users will not see or interact with this form. */}
<form
name={formName}
data-netlify="true"
data-netlify-honeypot="bot-field"
hidden
>
<input type="text" name="name" />
<input type="email" name="email" />
<textarea name="message"></textarea>
</form>
Add the Ant Design form
Next let’s create the actual form that users will interact with using the Ant Design form components.
We have 4 fields defined in our form.
- bot-field: hidden field for netlify-honepot to use.
- Name
- Message
On each of the form items we also add “rules” for validation. Ant forms will automatically apply these rules when the use hits submit. Upon error, the fields will show the message you define.
You can’t use the same form name for this form as you did on the html version.
You can give this form a throw away name because the html version of the form is the one that is actually used. Using the same name will cause errors on the Netlify side.
<Form
name="cf"
method="post"
onFinish={handleSubmit}
layout="vertical"
>
{/* This is the hidden field that the netlify-honeypot uses. */}
<Form.Item
label="Don't fill this out"
className={`hidden`}
style={{ display: `none` }}
name="bot-field"
>
<Input type={`hidden`} />
</Form.Item> <Form.Item
label="Name"
rules={[{ required: true, message: `Please enter your name.` }]}
name="name"
>
<Input
placeholder="Name"
prefix={<UserOutlined className="site-form-item-icon" />}
/>
</Form.Item> <Form.Item
label="Email"
rules={[{ required: true, type: `email`, message: `Please enter your email.` }]}
name="email"
>
<Input
placeholder="Your Email"
prefix={<MailOutlined className="site-form-item-icon" />}
/>
</Form.Item> <Form.Item
label="Message"
rules={[{ required: true, message: `Please enter your message.` }]}
name="message"
>
<TextArea
placeholder="Your Message"
rows={5}
/>
</Form.Item> <Form.Item>
<Button type="primary" htmlType="submit" disabled={false}>
Send
</Button>
</Form.Item>
</Form>
Handle the submission
Create a handleSubmit function. We’ve already told the form above to use handleSubmit on the form’s onFinish callback.
const handleSubmit = (values) => {
if (values[`bot-field`] === undefined) {
delete values[`bot-field`]
} fetch(`/`, {
method: `POST`,
headers: { 'Content-Type': `application/x-www-form-urlencoded` },
body: encode({
'form-name': formName,
...values,
}),
})
.then(() => showSuccess())
.catch(error => showError(error))
}
A couple of important things are happening in this function.
If the bot-field is empty, we have to remove it. It’s presence is enough for Netlify to treat it as if you are a bot. You could arguable add an else statement and just not even submit the form in the first place if the bot-field is not empty. It’s up to you, for this example we’ll just let it go.
It’s important the the body includes the ‘form-name’ field and that uses the formName constant.
You’ll also notice that we have to encode the body fields. To do this we’ll add an ‘encode’ function to the top of our file.
function encode(data) {
return Object.keys(data)
.map(key => encodeURIComponent(key) + `=` + encodeURIComponent(data[key]))
.join(`&`)
}
Lastly, handle the result
In the handleSubmit
function, we call showSuccess()
and showError()
.
You can do what you please with those methods. You’ll probably want to show the user a message about whether the form submitted successfully or not. You might consider using the React state to hide the form after submission and show a success message. In the full code below we’ve added the functions with console logs to get you started.
Hope this helped. The full code and an interactive example is below.
Full code
This is what it looks like.
To see an interactive example please visit the original post, linked below.
Originally published at https://joeczubiak.com on April 6, 2020.