Gatsby Contact Form

Without Backend, Sent via Email (or Slack)

Simple contact form

This guide will teach you how to create a beautiful and elegant form using Gatsby. Creating contact forms in Gatsby shouldn’t be a tedious task if your site is built using a static/jamstack approach.

Create the Gatsby app

(if you're starting a brand new project)

In case you're starting a brand new project, you'll need some initial steps. One of the most straightforward ways is to use the gatsby-cli package. To start:

  • Open the terminal and install the gatsby-cli package
    npm install -g gatsby-cli
  • Go to the directory where you will store your project. Initialize gatsby:
    npm init gatsby
  • When the installation has finished, you can start the server
    cd my-gatsby-site && npm run develop

Use your favorite code editor to work with files in ~/my-gatsby-site/src. You will be able to make a contact form there.

Add the `herotofu-react` package

To effortlessly handle form submissions, you can use the herotofu-react package. It will do all the form submission process work for you.

npm install --save herotofu-react

Create the contact form component

Create a new file called ContactForm.js in the src folder. You can use any type of field and any framework for building HTML, CSS, and Javascript. For now, let's stick with the standard "Name", "Email", and "Message" for our simple contact form. We're also going to use TailwindCSS to make it beautiful, but again, you can use your own customized CSS code too.

See how to install Gatsby Tailwind CSS here.

import { useFormData } from 'herotofu-react';

const ContactForm = () => {
  // TODO - update to the correct endpoint
  const { formState, getFormSubmitHandler } = useFormData('https://herotofu.com/start');

  return (
    <>
      {!!formState.status && <div className="py-2">Current form status is: {formState.status}</div>}
      <form onSubmit={getFormSubmitHandler()}>
        <div className="pt-0 mb-3">
          <input
            type="text"
            placeholder="Your name"
            name="name"
            className="focus:outline-none focus:ring relative w-full px-3 py-3 text-sm text-gray-600 placeholder-gray-400 bg-white border-0 rounded shadow outline-none"
            required
          />
        </div>
        <div className="pt-0 mb-3">
          <input
            type="email"
            placeholder="Email"
            name="email"
            className="focus:outline-none focus:ring relative w-full px-3 py-3 text-sm text-gray-600 placeholder-gray-400 bg-white border-0 rounded shadow outline-none"
            required
          />
        </div>
        <div className="pt-0 mb-3">
          <textarea
            placeholder="Your message"
            name="message"
            className="focus:outline-none focus:ring relative w-full px-3 py-3 text-sm text-gray-600 placeholder-gray-400 bg-white border-0 rounded shadow outline-none"
            required
          />
        </div>
        <div className="pt-0 mb-3">
          <button
            className="active:bg-blue-600 hover:shadow-lg focus:outline-none px-6 py-3 mb-1 mr-1 text-sm font-bold text-white uppercase transition-all duration-150 ease-linear bg-blue-500 rounded shadow outline-none"
            type="submit"
          >
            Send a message (simple)
          </button>
        </div>
      </form>
    </>
  );
};

export default ContactForm;

Embed component into your app

Open src/pages/index.js in your src folder, add contact form component. If it's an existing project, open the file where the contact form should appear. You need to:

  1. Import ContactForm — line number #2
  2. Display ContactForm — line number #10
import * as React from "react";
import ContactForm from "../ContactForm";

const IndexPage = () => {
  return (
    <main className="max-w-md p-6 mx-auto my-16 bg-gray-100">
      <title>Home Page</title>
      <h1 className="text-xl">Hello World!</h1>
      <div className="pt-6">
        <ContactForm />
      </div>
    </main>
  );
};

export default IndexPage;

Create the free HeroTofu forms backend

Head over to herotofu.com and create an account. It will handle the tedious and complicated form submission process for you. You'll get 14 free days of the free trial. Later, you can leave it with a free forever plan. For the sole purpose of using the contact form, it's usually more than enough.

HeroTofu registration is straightforward. Fill in the basic fields and then confirm your email address.

Herotofu signup

Once you have confirmed your email address, go to app.herotofu.com/forms to create your first form. Enter your name and email address where you want to receive your form submissions Slack and Zapier are also options, but you need to pay for them once the trial is over.

You'll get the endpoint URL once you hit Submit, so remember to copy that.

Herotofu Forms List

Use the created forms backend in your contact form

Once again, open the ContactForm.js file and fill in the form endpoint URL. You need to change the passed string to the useFormData() at the top of the component. It should look like this.

import { useFormData } from 'herotofu-react';

const ContactForm = () => {
  const { formState, getFormSubmitHandler } = useFormData('ENDPOINT_URL_OR_HEROTOFU_FORM_ID');

  // The rest of the code...

Done! Go ahead and test your contact form submission! You don't need to do any backend email work, as HeroTofu will handle everything.