Beginner5 minUpdated Mar 27, 2026

How to Add a Contact Form to Gatsby

Add a working contact form to your Gatsby site with React components and FormsList. No serverless functions or Gatsby Functions needed.

Prerequisites

  • A Gatsby project
  • A FormsList account (free)
  • Basic knowledge of React

TL;DR

To add a contact form to a Gatsby site, create a React component that submits to `https://formslist.com/f/your-form-id`. Since Gatsby generates static HTML, a form backend like FormsList handles submissions without needing serverless functions.

1

Create a FormsList form endpoint

Sign up for a free FormsList account and create a new form. Copy the endpoint URL from your dashboard.

// Your endpoint will look like this:
// https://formslist.com/f/YOUR_FORM_HASH
2

Create the contact form component

Create a React component in your Gatsby project. Gatsby uses React, so the pattern is the same as a standard React form — useState for status management and fetch for submission.

// src/components/ContactForm.jsx
import React, { useState } from "react"

export default function ContactForm() {
  const [status, setStatus] = useState("idle")

  async function handleSubmit(e) {
    e.preventDefault()
    setStatus("sending")

    const form = e.currentTarget
    const data = new FormData(form)

    try {
      const res = await fetch("https://formslist.com/f/YOUR_FORM_HASH", {
        method: "POST",
        body: data,
      })

      if (res.ok) {
        setStatus("sent")
        form.reset()
      } else {
        setStatus("error")
      }
    } catch {
      setStatus("error")
    }
  }

  return (
    <form onSubmit={handleSubmit} style={{ maxWidth: 480 }}>
      <div style={{ marginBottom: "1rem" }}>
        <label htmlFor="name" style={{ display: "block", fontWeight: 600 }}>Name</label>
        <input type="text" id="name" name="name" required style={{ width: "100%", padding: "0.5rem" }} />
      </div>
      <div style={{ marginBottom: "1rem" }}>
        <label htmlFor="email" style={{ display: "block", fontWeight: 600 }}>Email</label>
        <input type="email" id="email" name="email" required style={{ width: "100%", padding: "0.5rem" }} />
      </div>
      <div style={{ marginBottom: "1rem" }}>
        <label htmlFor="message" style={{ display: "block", fontWeight: 600 }}>Message</label>
        <textarea id="message" name="message" rows={4} required style={{ width: "100%", padding: "0.5rem" }} />
      </div>
      <button type="submit" disabled={status === "sending"}
        style={{ padding: "0.6rem 1.5rem", background: "#2563eb", color: "#fff", border: "none", borderRadius: 4, cursor: "pointer" }}>
        {status === "sending" ? "Sending..." : "Send Message"}
      </button>
      {status === "sent" && <p style={{ color: "green" }}>Message sent successfully!</p>}
      {status === "error" && <p style={{ color: "red" }}>Something went wrong. Please try again.</p>}
    </form>
  )
}
3

Add the form to a Gatsby page

Import the ContactForm component into a Gatsby page. Gatsby pages live in the src/pages/ directory and are automatically routed based on filename.

// src/pages/contact.jsx
import React from "react"
import Layout from "../components/Layout"
import ContactForm from "../components/ContactForm"

export default function ContactPage() {
  return (
    <Layout>
      <h1>Contact Us</h1>
      <p>Fill out the form below and we will get back to you within 24 hours.</p>
      <ContactForm />
    </Layout>
  )
}

export function Head() {
  return <title>Contact Us</title>
}
4

Deploy and test

Build your Gatsby site with `gatsby build` and deploy to your hosting provider (Netlify, Vercel, Gatsby Cloud, etc.). Submit a test message and verify it appears in your FormsList dashboard. Enable email notifications and integrations.

Frequently Asked Questions

Ready to collect form submissions?

Set up your form backend in under a minute. No server required, no complex configuration — just a simple endpoint for your forms.