Skip to content

Commit

Permalink
docs(www): add Build a Contact Form reference guide (#14564) (#14768)
Browse files Browse the repository at this point in the history
* Docs: add Build a Contact Form reference guide (#14564)

Adds a reference guide for building contact forms in Gatsby!
Has sections regarding:
	- Adding a Contact Form
	- Creating an Accessible Form
	- Sending Form Data
	  - with Netlify
	  - with Formspree
	  - Running Your Own Server
	- Other Resources (a cool Scott Tolinski tutorial)

* Adds a reference guide for building contact forms in Gatsby!

Has sections regarding:
- Adding a Contact Form
- Creating an Accessible Form
- Sending Form Data
- with Netlify
- with Formspree
- Running Your Own Server
- Other Resources (a cool Scott Tolinski tutorial)

This time, actually includes reference guide! ✨

* Adds fixes for all aforementioned proposed changes, including:
	- Removes `Adding a Contact Form` Heading
	- Fixes link to `Adding Forms`
	- Fixes `Run your own server` case
	- diffs netlify code example, as requested
	- adds link to netlify form-handling doc
	- adds reference to formspree honeypot for spam prevention (good catch @marcysutton!)

* Adds subheading to gracefully transition between sections

Adds subheading to indicate transition between conceptual form example and practical how-to's
  • Loading branch information
dyyyl authored and Marcy Sutton committed Jun 20, 2019
1 parent 5c71b94 commit 72b918a
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 0 deletions.
150 changes: 150 additions & 0 deletions docs/docs/building-a-contact-form.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
---
title: Building a Contact Form
---

This guide covers how to create a contact form in a Gatsby site, along with an overview of some strategies for handling form data that has been submitted.

Gatsby is built on top of React. So anything that is possible with a React form is possible in Gatsby. Additional details about how to add forms to gatsby can be found in the [Adding Forms](/docs/adding-forms/) section.

## Creating an Accessible Form

Faulty forms are a common barrier to a website's accessibility, and can be especially problematic if you use a keyboard and screen reader to navigate the web. Forms should be clearly and intuitively organized into groups of related information, and each form field should be identified with a proper label.

More information on creating accessible forms can be found in [WebAIM's article](https://webaim.org/techniques/forms/) on the subject.

## Sending Form Data

When you submit a form, the corresponding data is typically sent to a server to be handled in some manner. More in-depth information on sending form data can be found [on MDN](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data).

Each method detailed below will start with the following contact form:

```jsx:title=src/pages/contact.js
<form method="post" action="#">
<label>
Name
<input type="text" name="name" id="name" />
</label>
<label>
Email
<input type="email" name="email" id="email" />
</label>
<label>
Subject
<input type="text" name="subject" id="subject" />
</label>
<label>
Message
<textarea name="message" id="message" rows="5" />
</label>
<button type="submit">Send</button>
<input type="reset" value="Clear" />
</form>
```

## Form submission options in Gatsby

### Netlify

If you're hosting your site with Netlify, you gain access to their excellent [form handling feature](https://www.netlify.com/docs/form-handling/).

Setting this up only invloves adding a few form attributes:

```diff:title=src/pages/contact.js
- <form method="post" action="#">
+ <form method="post" netlify-honeypot="bot-field" data-netlify="true">
+ <input type="hidden" name="bot-field" />
...
```

Now, all submissions to your form will appear in the Forms tab of your site dashboard. By adding the form attribute `netlify-honeypot="bot-field"` and a corresponding hidden input, Netlify will know to quietly reject any spam submissions you may receive.

More information on Netlify Forms can be found [on their website](https://www.netlify.com/docs/form-handling/).

### Formspree

Formspree offers a generous free-tier service for handling form submissions on static sites. This makes it a great tool for having form submissions sent directly to an email address of your choosing, with very little setup required.

In order to begin leveraging Formspree's features, you must add a form action directing the http POST method to the Formspree API (substituting your chosen email), as well as changing the `name` attribute of the email input to `name="_replyto"`.

```jsx:title=src/pages/contact.js
<form method="post" action="https://formspree.io/[email protected]">
...
<label>
Email
<input type="email" name="_replyto" />
</label>
...
</form>
```

Once you've made the changes you can submit your own form for the first time and register using the email Formspree will send you, and all subsequent form submissions will be sent to your email address. You can find more information on the registration process or setup [on their website](https://formspree.io/).

All forms set up in this way come with ReCAPTCHA by default, but you can also enable Honeypot spam filtering by adding a hidden input element with the `name="_gotcha"` field.

```jsx
<input type="text" name="_gotcha" style="display:none" />
```

Because the input is hidden, Formspree will know that only a bot could have made the submission, and it will be silently ignore it!

### Run your own server

If your form data requires a significant amount of business logic to handle, creating your own service might make the most sense. The most popular solution to this is writing an HTTP server - this can be done in many languages including PHP, Ruby, GoLang, or in our case Node.js with [Express](https://expressjs.com/).

An initial implementation of a server using express, body-parser, and nodemailer may look like this:

```javascript:title=handleForm.js
const bodyParser = require("body-parser")
const express = require("express")
const nodemailer = require("nodemailer")

const app = express()
app.use(bodyParser.urlencoded())

const contactAddress = "[email protected]"

const mailer = nodemailer.createTransport({
service: "Gmail",
auth: {
user: process.env.production.GMAIL_ADDRESS,
pass: process.env.production.GMAIL_PASSWORD,
},
})

app.post("/contact", function(req, res) {
mailer.sendMail(
{
from: req.body.from,
to: [contactAddress],
subject: req.body.subject || "[No subject]",
html: req.body.message || "[No message]",
},
function(err, info) {
if (err) return res.status(500).send(err)
res.json({ success: true })
}
)
})

app.listen(3000)
```

This initial implementation listens for POST requests to `/contact`, and sends you an email with the submitted form data. You can deploy this server with services such as [Now](https://zeit.co/now).

Once deployed, note the url of the deployment (something like `my-project-abcd123.now.sh`), and use it as your form action:

```jsx:title=src/pages/contact.js
<form method="post" action="my-project-abcd123.now.sh/contact">
...
</form>
```

Now, all subsequent form submissions will be sent to your email address!

For an in-depth guide on running your own mail server, you can refer to [this awesome guide by DataFire](https://medium.com/datafire-io/simple-backends-four-ways-to-implement-a-contact-us-form-on-a-static-website-10fc430984a4).

## Other resources

If you have any issues or if you want to learn more about implementing your own contact form in Gatsby, check out this tutorial from Scott Tolinski:

`youtube: hF7xJhzrr9s`
2 changes: 2 additions & 0 deletions www/src/data/sidebars/doc-links.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@
link: /docs/building-a-site-with-authentication/
- title: Adding Forms
link: /docs/adding-forms/
- title: Building a Contact Form
link: /docs/building-a-contact-form
- title: Adding a 404 Page
link: /docs/add-404-page/
- title: Adding an SEO Component
Expand Down

0 comments on commit 72b918a

Please sign in to comment.